Skip to content

Commit

Permalink
Type aliasing (deepmap#232)
Browse files Browse the repository at this point in the history
* Add aliasable types logic and option

* Update templates

* Re-generate examples
  • Loading branch information
natsukagami committed Jan 29, 2021
1 parent 8f32db3 commit 6abd8bc
Show file tree
Hide file tree
Showing 15 changed files with 44 additions and 23 deletions.
6 changes: 5 additions & 1 deletion cmd/oapi-codegen/oapi-codegen.go
Expand Up @@ -43,6 +43,7 @@ var (
flagImportMapping string
flagExcludeSchemas string
flagConfigFile string
flagAliasTypes bool
)

type configuration struct {
Expand All @@ -68,6 +69,7 @@ func main() {
flag.StringVar(&flagImportMapping, "import-mapping", "", "A dict from the external reference to golang package path")
flag.StringVar(&flagExcludeSchemas, "exclude-schemas", "", "A comma separated list of schemas which must be excluded from generation")
flag.StringVar(&flagConfigFile, "config", "", "a YAML config file that controls oapi-codegen behavior")
flag.BoolVar(&flagAliasTypes, "alias-types", false, "Alias type declarations of possible")
flag.Parse()

if flag.NArg() < 1 {
Expand All @@ -87,7 +89,9 @@ func main() {
cfg.PackageName = codegen.ToCamelCase(nameParts[0])
}

opts := codegen.Options{}
opts := codegen.Options{
AliasTypes: flagAliasTypes,
}
for _, g := range cfg.GenerateTargets {
switch g {
case "client":
Expand Down
2 changes: 1 addition & 1 deletion examples/petstore-expanded/chi/api/petstore.gen.go

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

2 changes: 1 addition & 1 deletion examples/petstore-expanded/echo/api/petstore-types.gen.go

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

2 changes: 1 addition & 1 deletion examples/petstore-expanded/petstore-client.gen.go

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

4 changes: 2 additions & 2 deletions internal/test/client/client.gen.go

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

4 changes: 2 additions & 2 deletions internal/test/components/components.gen.go

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

4 changes: 2 additions & 2 deletions internal/test/schemas/schemas.gen.go

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

6 changes: 3 additions & 3 deletions internal/test/server/server.gen.go

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

2 changes: 2 additions & 0 deletions pkg/codegen/codegen.go
Expand Up @@ -38,6 +38,7 @@ type Options struct {
EmbedSpec bool // Whether to embed the swagger spec in the generated code
SkipFmt bool // Whether to skip go imports on the generated code
SkipPrune bool // Whether to skip pruning unused components on the generated code
AliasTypes bool // Whether to alias types if possible
IncludeTags []string // Only include operations that have one of these tags. Ignored when empty.
ExcludeTags []string // Exclude operations that have one of these tags. Ignored when empty.
UserTemplates map[string]string // Override built-in templates from user-provided files
Expand Down Expand Up @@ -110,6 +111,7 @@ func Generate(swagger *openapi3.Swagger, packageName string, opts Options) (stri
}

// This creates the golang templates text package
TemplateFunctions["opts"] = func() Options { return opts }
t := template.New("oapi-codegen").Funcs(TemplateFunctions)
// This parses all of our own template files into the template object
// above
Expand Down
7 changes: 5 additions & 2 deletions pkg/codegen/operations.go
Expand Up @@ -333,8 +333,11 @@ type RequestBodyDefinition struct {
}

// Returns the Go type definition for a request body
func (r RequestBodyDefinition) TypeDef() string {
return r.Schema.TypeDecl()
func (r RequestBodyDefinition) TypeDef(opID string) *TypeDefinition {
return &TypeDefinition{
TypeName: fmt.Sprintf("%s%sRequestBody", opID, r.NameTag),
Schema: r.Schema,
}
}

// Returns whether the body is a custom inline type, or pre-defined. This is
Expand Down
8 changes: 8 additions & 0 deletions pkg/codegen/schema.go
Expand Up @@ -13,6 +13,8 @@ type Schema struct {
GoType string // The Go type needed to represent the schema
RefType string // If the type has a type name, this is set

ArrayType *Schema // The schema of array element

EnumValues map[string]string // Enum values

Properties []Property // For an object, the fields with names
Expand Down Expand Up @@ -81,6 +83,11 @@ type TypeDefinition struct {
Schema Schema
}

func (t *TypeDefinition) CanAlias() bool {
return t.Schema.IsRef() || /* actual reference */
(t.Schema.ArrayType != nil && t.Schema.ArrayType.IsRef()) /* array to ref */
}

func PropertiesEqual(a, b Property) bool {
return a.JsonFieldName == b.JsonFieldName && a.Schema.TypeDecl() == b.Schema.TypeDecl() && a.Required == b.Required
}
Expand Down Expand Up @@ -235,6 +242,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
if err != nil {
return Schema{}, errors.Wrap(err, "error generating type for array")
}
outSchema.ArrayType = &arrayType
outSchema.GoType = "[]" + arrayType.TypeDecl()
outSchema.Properties = arrayType.Properties
case "integer":
Expand Down
2 changes: 1 addition & 1 deletion pkg/codegen/templates/param-types.tmpl
@@ -1,6 +1,6 @@
{{range .}}{{$opid := .OperationId}}
{{range .TypeDefinitions}}
// {{.TypeName}} defines parameters for {{$opid}}.
type {{.TypeName}} {{.Schema.TypeDecl}}
type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
{{end}}
{{end}}
6 changes: 4 additions & 2 deletions pkg/codegen/templates/request-bodies.tmpl
@@ -1,6 +1,8 @@
{{range .}}{{$opid := .OperationId}}
{{range .Bodies}}
// {{$opid}}RequestBody defines body for {{$opid}} for application/json ContentType.
type {{$opid}}{{.NameTag}}RequestBody {{.TypeDef}}
{{with .TypeDef $opid}}
// {{.TypeName}} defines body for {{$opid}} for application/json ContentType.
type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
{{end}}
{{end}}
{{end}}
10 changes: 6 additions & 4 deletions pkg/codegen/templates/templates.gen.go

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

2 changes: 1 addition & 1 deletion pkg/codegen/templates/typedef.tmpl
@@ -1,6 +1,6 @@
{{range .Types}}
// {{.TypeName}} defines model for {{.JsonName}}.
type {{.TypeName}} {{.Schema.TypeDecl}}
type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
{{- if gt (len .Schema.EnumValues) 0 }}
// List of {{ .TypeName }}
const (
Expand Down

0 comments on commit 6abd8bc

Please sign in to comment.