Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/test/issues/issue-1530/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package: issue1530
generate:
models: true
output: issue1530.gen.go
3 changes: 3 additions & 0 deletions internal/test/issues/issue-1530/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package issue1530

//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml issue1530.yaml
126 changes: 126 additions & 0 deletions internal/test/issues/issue-1530/issue1530.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions internal/test/issues/issue-1530/issue1530.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
paths:
/config:
post:
summary: Save configuration
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ConfigSaveReq"
responses:
"200":
description: Configuration saved successfully
components:
schemas:
ConfigHttp:
type: object
properties:
config_type:
type: string
host:
type: string
port:
type: integer
user:
type: string
password:
type: string
required:
- config_type
- host
- port
ConfigSaveReq:
oneOf:
- $ref: "#/components/schemas/ConfigHttp"
- $ref: "#/components/schemas/ConfigSsh"
discriminator:
propertyName: config_type
mapping:
ssh_server: "#/components/schemas/ConfigSsh"
apache_server: "#/components/schemas/ConfigHttp"
web_server: "#/components/schemas/ConfigHttp"
another_server: "#/components/schemas/ConfigHttp"
ConfigSsh:
type: object
properties:
config_type:
type: string
host:
type: string
port:
type: integer
user:
type: string
private_key:
type: string
required:
- config_type
51 changes: 51 additions & 0 deletions internal/test/issues/issue-1530/issue1530_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package issue1530_test

import (
"testing"

issue1530 "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-1530"
"github.com/stretchr/testify/require"
)

func TestIssue1530(t *testing.T) {
httpConfigTypes := []string{
"another_server",
"apache_server",
"web_server",
}

for _, configType := range httpConfigTypes {
t.Run("http-"+configType, func(t *testing.T) {
saveReq := issue1530.ConfigSaveReq{}
err := saveReq.FromConfigHttp(issue1530.ConfigHttp{
ConfigType: configType,
Host: "example.com",
})
require.NoError(t, err)

cfg, err := saveReq.AsConfigHttp()
require.NoError(t, err)
require.Equal(t, configType, cfg.ConfigType)

cfgByDiscriminator, err := saveReq.ValueByDiscriminator()
require.NoError(t, err)
require.Equal(t, cfg, cfgByDiscriminator)
})
}

t.Run("ssh", func(t *testing.T) {
saveReq := issue1530.ConfigSaveReq{}
err := saveReq.FromConfigSsh(issue1530.ConfigSsh{
ConfigType: "ssh_server",
})
require.NoError(t, err)

cfg, err := saveReq.AsConfigSsh()
require.NoError(t, err)
require.Equal(t, "ssh_server", cfg.ConfigType)

cfgByDiscriminator, err := saveReq.ValueByDiscriminator()
require.NoError(t, err)
require.Equal(t, cfg, cfgByDiscriminator)
})
}
3 changes: 1 addition & 2 deletions pkg/codegen/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,6 @@ func generateUnion(outSchema *Schema, elements openapi3.SchemaRefs, discriminato
if v == element.Ref {
outSchema.Discriminator.Mapping[k] = elementSchema.GoType
mapped = true
break
}
}
// Implicit mapping.
Expand All @@ -949,7 +948,7 @@ func generateUnion(outSchema *Schema, elements openapi3.SchemaRefs, discriminato
outSchema.UnionElements = append(outSchema.UnionElements, UnionElement(elementSchema.GoType))
}

if (outSchema.Discriminator != nil) && len(outSchema.Discriminator.Mapping) != len(elements) {
if (outSchema.Discriminator != nil) && len(outSchema.Discriminator.Mapping) < len(elements) {
return errors.New("discriminator: not all schemas were mapped")
}

Expand Down
37 changes: 21 additions & 16 deletions pkg/codegen/templates/union.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{{$typeName := .TypeName -}}
{{$discriminator := .Schema.Discriminator}}
{{$properties := .Schema.Properties -}}
{{$numberOfUnionTypes := len .Schema.UnionElements -}}
{{range .Schema.UnionElements}}
{{$element := . -}}
// As{{ .Method }} returns the union data inside the {{$typeName}} as a {{.}}
Expand All @@ -14,16 +15,18 @@
// From{{ .Method }} overwrites any union data inside the {{$typeName}} as the provided {{.}}
func (t *{{$typeName}}) From{{ .Method }} (v {{.}}) error {
{{if $discriminator -}}
{{range $value, $type := $discriminator.Mapping -}}
{{if eq $type $element -}}
{{$hasProperty := false -}}
{{range $properties -}}
{{if eq .GoFieldName $discriminator.PropertyName -}}
t.{{$discriminator.PropertyName}} = "{{$value}}"
{{$hasProperty = true -}}
{{if eq $numberOfUnionTypes (len $discriminator.Mapping) -}}
{{range $value, $type := $discriminator.Mapping -}}
{{if eq $type $element -}}
{{$hasProperty := false -}}
{{range $properties -}}
{{if eq .GoFieldName $discriminator.PropertyName -}}
t.{{$discriminator.PropertyName}} = "{{$value}}"
{{$hasProperty = true -}}
{{end -}}
{{end -}}
{{if not $hasProperty}}v.{{$discriminator.PropertyName}} = "{{$value}}"{{end}}
{{end -}}
{{if not $hasProperty}}v.{{$discriminator.PropertyName}} = "{{$value}}"{{end}}
{{end -}}
{{end -}}
{{end -}}
Expand All @@ -35,16 +38,18 @@
// Merge{{ .Method }} performs a merge with any union data inside the {{$typeName}}, using the provided {{.}}
func (t *{{$typeName}}) Merge{{ .Method }} (v {{.}}) error {
{{if $discriminator -}}
{{range $value, $type := $discriminator.Mapping -}}
{{if eq $type $element -}}
{{$hasProperty := false -}}
{{range $properties -}}
{{if eq .GoFieldName $discriminator.PropertyName -}}
t.{{$discriminator.PropertyName}} = "{{$value}}"
{{$hasProperty = true -}}
{{if eq $numberOfUnionTypes (len $discriminator.Mapping) -}}
{{range $value, $type := $discriminator.Mapping -}}
{{if eq $type $element -}}
{{$hasProperty := false -}}
{{range $properties -}}
{{if eq .GoFieldName $discriminator.PropertyName -}}
t.{{$discriminator.PropertyName}} = "{{$value}}"
{{$hasProperty = true -}}
{{end -}}
{{end -}}
{{if not $hasProperty}}v.{{$discriminator.PropertyName}} = "{{$value}}"{{end}}
{{end -}}
{{if not $hasProperty}}v.{{$discriminator.PropertyName}} = "{{$value}}"{{end}}
{{end -}}
{{end -}}
{{end -}}
Expand Down