diff --git a/_testdata/positive/servers.json b/_testdata/positive/servers.json index 5aff6bbbc..e8124268c 100644 --- a/_testdata/positive/servers.json +++ b/_testdata/positive/servers.json @@ -38,6 +38,15 @@ { "x-ogen-server-name": "const", "url": "https://cdn.example.com/v1" + }, + { + "x-ogen-server-name": "optionalVars", + "url": "https://cdn.example.com/{version}", + "variables": { + "version": { + "default": "v1" + } + } } ], "info": { diff --git a/gen/_template/servers.tmpl b/gen/_template/servers.tmpl index d18bf16ed..dc40ad488 100644 --- a/gen/_template/servers.tmpl +++ b/gen/_template/servers.tmpl @@ -50,6 +50,7 @@ func (s {{ $s.Name }}) Build() (string, error) { } {{- range $p := $s.Params }} s.{{ $p.Name }} = zeroOr(s.{{ $p.Name }}, {{ quote $p.Spec.Default }}) + {{- if $p.Spec.Enum }} // Validate {{ quote $p.Spec.Name }} switch s.{{ $p.Name }} { {{- range $e := $p.Spec.Enum }} @@ -59,6 +60,7 @@ func (s {{ $s.Name }}) Build() (string, error) { return "", errors.Errorf("param %q: unexpected value %q", {{ quote $p.Spec.Name }}, s.{{ $p.Name }}) } {{- end }} + {{- end }} return fmt.Sprintf({{ $s.FormatString | quote }}, {{- range $p := $s.Params }} s.{{ $p.Name }}, diff --git a/internal/integration/test_servers/oas_servers_gen.go b/internal/integration/test_servers/oas_servers_gen.go index 5e38188c8..6e389156d 100644 --- a/internal/integration/test_servers/oas_servers_gen.go +++ b/internal/integration/test_servers/oas_servers_gen.go @@ -129,6 +129,53 @@ func (s PrefixServer) Build() (string, error) { ), nil } +// OptionalVarsServer is a server URL template. +type OptionalVarsServer struct { + Version string `json:"version" yaml:"version"` +} + +// MustPath returns the computed path. It panics if any error occurs. +func (s OptionalVarsServer) MustPath() string { + return errors.Must(s.Path()) +} + +// Path returns the computed path. +func (s OptionalVarsServer) Path() (string, error) { + raw, err := s.Build() + if err != nil { + return "", err + } + u, err := url.Parse(raw) + if err != nil { + return "", err + } + return u.Path, nil +} + +// MustBuild returns the computed server URL. It panics if any error occurs. +func (s OptionalVarsServer) MustBuild() string { + return errors.Must(s.Build()) +} + +// Build returns the computed server URL. +// +// If variable is empty, it uses the default value. +// If spec defines an enum and given value is not in the enum, it returns an error. +// +// Notice that given values will not be escaped and may cause invalid URL. +func (s OptionalVarsServer) Build() (string, error) { + zeroOr := func(s string, def string) string { + if s == "" { + return def + } + return s + } + s.Version = zeroOr(s.Version, "v1") + return fmt.Sprintf("https://cdn.example.com/%s", + s.Version, + ), nil +} + type serverConst string // MustPath returns the computed path. It panics if any error occurs.