Repository: deepmap/oapi-codegen (go)

Issue:
Missing Enum Values and validation code
I am trying to generate Golang code for following openapi 3 spec. I have doubts regarding Go code generation for enum related types. 

```yaml
openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification
  termsOfService: http://swagger.io/terms/
  contact:
    name: Swagger API Team
    email: apiteam@swagger.io
    url: http://swagger.io
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: http://petstore.swagger.io/api
paths:
  /pets:
    post:
      summary: Post a PetType Information.
      description: Post a PetType Information.
      operationId: postPets
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'
      responses:
        '200':
          description: Updated
    get:
      summary: Returns a pet info by given petType.
      description: Get Pet Infrmation based on pet type.
      operationId: getPets
      parameters:
        - $ref: '#/components/parameters/PetType'
        - in: query
          name: petColor
          schema:
            type: string
      responses:
        '200':
          description: Get Pet Type 
          content:
            application/json: 
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Cat'
                  - $ref: '#/components/schemas/Dog'
components:
  schemas:
    Pet:
      type: object
      properties:
        color:
          $ref: '#/components/schemas/Color'
        name:
          type: string
          nullable: true
        owners:
          type: array
          nullable: false
          items:
            type: object
            properties:
              ownerName:
                type: string
              ownerAddress:
                type: string
                nullable: true
    Dog:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          required:
            - bark
          properties:
            bark:
              type: boolean
            breed:  
              type: string
              enum: [Dingo, Husky, Retriever, Shepherd]
              nullable: true
    Cat:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            hunts:
              type: boolean
              nullable: true
            age:
              type: number
              format: float
              nullable: true
    Color:
      type: string
      nullable: true
      enum: 
        - black
        - white
        - red
        - green
        - blue
    PetTypeEnum:
      type: string
      enum:
        - cat
        - dog
  parameters:
    PetType:
      name: petType
      in: query
      required: true
      schema:
        $ref: '#/components/schemas/PetTypeEnum'
```
In the generate go code, enums defined in the YAML such as 'Color' and 'PetTypeEnum' are generated as String type which is expected.
```Go
type Color string 
```
But there are no 'const' generated for possible set of enum values defined in the input spec. I was exepcting following code to be generated with above code. 
```Go
const (
        BLACK Color = "black"
        WHITE Color = "white"
        RED Color = "red"
        GREEN Color = "green"
        BLUE Color = "blue"
) 
```
Is this behaviour by design? I also do not see any validation function which will validate the input value against the possible enum values for a given field.

Pull request description:
feat: typed enums
This PR adds support for generating typed enum constants for enums in all places. It replaces #181 and properly fixes #54.

There is also a small fix for propagating the `servers` property declared locally on the operation.

Patch:
diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go
index 5474eee..f544e9a 100644
--- a/pkg/codegen/codegen.go
+++ b/pkg/codegen/codegen.go
@@ -297,6 +297,11 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.Swagger, op
 		return "", errors.Wrap(err, "error generating Go types for operation parameters")
 	}
 
+	enumsOut, err := GenerateEnums(t, allTypes)
+	if err != nil {
+		return "", errors.Wrap(err, "error generating code for type enums")
+	}
+
 	typesOut, err := GenerateTypes(t, allTypes)
 	if err != nil {
 		return "", errors.Wrap(err, "error generating code for type definitions")
@@ -307,7 +312,7 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.Swagger, op
 		return "", errors.Wrap(err, "error generating allOf boilerplate")
 	}
 
-	typeDefinitions := strings.Join([]string{typesOut, paramTypesOut, allOfBoilerplate}, "")
+	typeDefinitions := strings.Join([]string{enumsOut, typesOut, paramTypesOut, allOfBoilerplate}, "")
 	return typeDefinitions, nil
 }
 
@@ -514,6 +519,36 @@ func GenerateTypes(t *template.Template, types []TypeDefinition) (string, error)
 	return buf.String(), nil
 }
 
+func GenerateEnums(t *template.Template, types []TypeDefinition) (string, error) {
+	var buf bytes.Buffer
+	w := bufio.NewWriter(&buf)
+	c := Constants{
+		EnumDefinitions: []EnumDefinition{},
+	}
+	for _, tp := range types {
+		if len(tp.Schema.EnumValues) > 0 {
+			wrapper := ""
+			if tp.Schema.GoType == "string" {
+				wrapper = `"`
+			}
+			c.EnumDefinitions = append(c.EnumDefinitions, EnumDefinition{
+				Schema:       tp.Schema,
+				TypeName:     tp.TypeName,
+				ValueWrapper: wrapper,
+			})
+		}
+	}
+	err := t.ExecuteTemplate(w, "constants.tmpl", c)
+	if err != nil {
+		return "", errors.Wrap(err, "error generating enums")
+	}
+	err = w.Flush()
+	if err != nil {
+		return "", errors.Wrap(err, "error flushing output buffer for enums")
+	}
+	return buf.String(), nil
+}
+
 // Generate our import statements and package definition.
 func GenerateImports(t *template.Template, externalImports []string, packageName string) (string, error) {
 	var buf bytes.Buffer
diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go
index 6e788b0..cbfe2ed 100644
--- a/pkg/codegen/operations.go
+++ b/pkg/codegen/operations.go
@@ -392,6 +392,9 @@ func OperationDefinitions(swagger *openapi3.Swagger) ([]OperationDefinition, err
 		pathOps := pathItem.Operations()
 		for _, opName := range SortedOperationsKeys(pathOps) {
 			op := pathOps[opName]
+			if pathItem.Servers != nil {
+				op.Servers = &pathItem.Servers
+			}
 			// We rely on OperationID to generate function names, it's required
 			if op.OperationID == "" {
 				op.OperationID, err = generateDefaultOperationID(opName, requestPath)
diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go
index aa49fad..ef89b4e 100644
--- a/pkg/codegen/schema.go
+++ b/pkg/codegen/schema.go
@@ -79,9 +79,18 @@ func (p Property) GoTypeDef() string {
 	return typeDef
 }
 
+// EnumDefinition holds type information for enum
+type EnumDefinition struct {
+	Schema       Schema
+	TypeName     string
+	ValueWrapper string
+}
+
 type Constants struct {
 	// SecuritySchemeProviderNames holds all provider names for security schemes.
 	SecuritySchemeProviderNames []string
+	// EnumDefinitions holds type and value information for all enums
+	EnumDefinitions []EnumDefinition
 }
 
 // TypeDefinition describes a Go type definition in generated code.
@@ -96,15 +105,14 @@ type Constants struct {
 //        type: string
 type TypeDefinition struct {
 	// The name of the type, eg, type <...> Person
-	TypeName        string
+	TypeName string
 
 	// The name of the corresponding JSON description, as it will sometimes
 	// differ due to invalid characters.
-	JsonName        string
+	JsonName string
 
 	// This is the Schema wrapper is used to populate the type description
-	Schema          Schema
-
+	Schema Schema
 }
 
 // ResponseTypeDefinition is an extension of TypeDefinition, specifically for
@@ -115,7 +123,7 @@ type ResponseTypeDefinition struct {
 	ContentTypeName string
 
 	// The type name of a response model.
-	ResponseName    string
+	ResponseName string
 }
 
 func (t *TypeDefinition) CanAlias() bool {
@@ -266,83 +274,119 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
 			outSchema.GoType = GenStructFromSchema(outSchema)
 		}
 		return outSchema, nil
-	} else {
-		f := schema.Format
+	} else if len(schema.Enum) > 0 {
+		err := resolveType(schema, path, &outSchema)
+		if err != nil {
+			return Schema{}, errors.Wrap(err, "error resolving primitive type")
+		}
+		enumValues := make([]string, len(schema.Enum))
+		for i, enumValue := range schema.Enum {
+			enumValues[i] = fmt.Sprintf("%v", enumValue)
+		}
 
-		switch t {
-		case "array":
-			// For arrays, we'll get the type of the Items and throw a
-			// [] in front of it.
-			arrayType, err := GenerateGoSchema(schema.Items, path)
-			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":
-			// We default to int if format doesn't ask for something else.
-			if f == "int64" {
-				outSchema.GoType = "int64"
-			} else if f == "uint64" {
-				outSchema.GoType = "uint64"
-			} else if f == "int32" {
-				outSchema.GoType = "int32"
-			} else if f == "uint32" {
-				outSchema.GoType = "uint32"
-			} else if f == "" {
-				outSchema.GoType = "int"
+		sanitizedValues := SanitizeEnumNames(enumValues)
+		outSchema.EnumValues = make(map[string]string, len(sanitizedValues))
+		var constNamePath []string
+		for k, v := range sanitizedValues {
+			if v == "" {
+				constNamePath = append(path, "Empty")
 			} else {
-				return Schema{}, fmt.Errorf("invalid integer format: %s", f)
+				constNamePath = append(path, k)
 			}
-		case "number":
-			// We default to float for "number"
-			if f == "double" {
-				outSchema.GoType = "float64"
-			} else if f == "float" || f == "" {
-				outSchema.GoType = "float32"
-			} else {
-				return Schema{}, fmt.Errorf("invalid number format: %s", f)
-			}
-		case "boolean":
-			if f != "" {
-				return Schema{}, fmt.Errorf("invalid format (%s) for boolean", f)
-			}
-			outSchema.GoType = "bool"
-		case "string":
-			enumValues := make([]string, len(schema.Enum))
-			var ok bool
-			for i, enumValue := range schema.Enum {
-				enumValues[i], ok = enumValue.(string)
-				if !ok {
-					return Schema{}, fmt.Errorf("expected enum to contain strings, found a %T", enumValue)
-				}
+			outSchema.EnumValues[SchemaNameToTypeName(PathToTypeName(constNamePath))] = v
+		}
+		if len(path) > 1 { // handle additional type only on non-toplevel types
+			typeName := SchemaNameToTypeName(PathToTypeName(path))
+			typeDef := TypeDefinition{
+				TypeName: typeName,
+				JsonName: strings.Join(path, "."),
+				Schema:   outSchema,
 			}
+			outSchema.AdditionalTypes = append(outSchema.AdditionalTypes, typeDef)
+			outSchema.RefType = typeName
+		}
+		//outSchema.RefType = typeName
+	} else {
+		err := resolveType(schema, path, &outSchema)
+		if err != nil {
+			return Schema{}, errors.Wrap(err, "error resolving primitive type")
+		}
+	}
+	return outSchema, nil
+}
 
-			outSchema.EnumValues = SanitizeEnumNames(enumValues)
-
-			// Special case string formats here.
-			switch f {
-			case "byte":
-				outSchema.GoType = "[]byte"
-			case "email":
-				outSchema.GoType = "openapi_types.Email"
-			case "date":
-				outSchema.GoType = "openapi_types.Date"
-			case "date-time":
-				outSchema.GoType = "time.Time"
-			case "json":
-				outSchema.GoType = "json.RawMessage"
-				outSchema.SkipOptionalPointer = true
-			default:
-				// All unrecognized formats are simply a regular string.
-				outSchema.GoType = "string"
-			}
+// resolveType resolves primitive  type or array for schema
+func resolveType(schema *openapi3.Schema, path []string, outSchema *Schema) error {
+	f := schema.Format
+	t := schema.Type
+
+	switch t {
+	case "array":
+		// For arrays, we'll get the type of the Items and throw a
+		// [] in front of it.
+		arrayType, err := GenerateGoSchema(schema.Items, path)
+		if err != nil {
+			return errors.Wrap(err, "error generating type for array")
+		}
+		outSchema.ArrayType = &arrayType
+		outSchema.GoType = "[]" + arrayType.TypeDecl()
+		additionalTypes := arrayType.GetAdditionalTypeDefs()
+		// Check also types defined in array item
+		if len(additionalTypes) > 0 {
+			outSchema.AdditionalTypes = append(outSchema.AdditionalTypes, additionalTypes...)
+		}
+		outSchema.Properties = arrayType.Properties
+	case "integer":
+		// We default to int if format doesn't ask for something else.
+		if f == "int64" {
+			outSchema.GoType = "int64"
+		} else if f == "uint64" {
+			outSchema.GoType = "uint64"
+		} else if f == "int32" {
+			outSchema.GoType = "int32"
+		} else if f == "uint32" {
+			outSchema.GoType = "uint32"
+		} else if f == "" {
+			outSchema.GoType = "int"
+		} else {
+			return fmt.Errorf("invalid integer format: %s", f)
+		}
+	case "number":
+		// We default to float for "number"
+		if f == "double" {
+			outSchema.GoType = "float64"
+		} else if f == "float" || f == "" {
+			outSchema.GoType = "float32"
+		} else {
+			return fmt.Errorf("invalid number format: %s", f)
+		}
+	case "boolean":
+		if f != "" {
+			return fmt.Errorf("invalid format (%s) for boolean", f)
+		}
+		outSchema.GoType = "bool"
+	case "string":
+		// Special case string formats here.
+		switch f {
+		case "byte":
+			outSchema.GoType = "[]byte"
+		case "email":
+			outSchema.GoType = "openapi_types.Email"
+		case "date":
+			outSchema.GoType = "openapi_types.Date"
+		case "date-time":
+			outSchema.GoType = "time.Time"
+		case "json":
+			outSchema.GoType = "json.RawMessage"
+			outSchema.SkipOptionalPointer = true
 		default:
-			return Schema{}, fmt.Errorf("unhandled Schema type: %s", t)
+			// All unrecognized formats are simply a regular string.
+			outSchema.GoType = "string"
 		}
+	default:
+		return fmt.Errorf("unhandled Schema type: %s", t)
 	}
-	return outSchema, nil
+	return nil
 }
 
 // This describes a Schema, a type definition.
@@ -531,7 +575,7 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) {
 	// so we'll return the parameter as a string, not bothering to decode it.
 	if len(param.Content) > 1 {
 		return Schema{
-			GoType: "string",
+			GoType:      "string",
 			Description: param.Description,
 		}, nil
 	}
@@ -541,7 +585,7 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) {
 	if !found {
 		// If we don't have json, it's a string
 		return Schema{
-			GoType: "string",
+			GoType:      "string",
 			Description: param.Description,
 		}, nil
 	}
diff --git a/pkg/codegen/templates/constants.tmpl b/pkg/codegen/templates/constants.tmpl
index 5b616d0..314d817 100644
--- a/pkg/codegen/templates/constants.tmpl
+++ b/pkg/codegen/templates/constants.tmpl
@@ -5,3 +5,13 @@ const (
 {{end}}
 )
 {{end}}
+{{if gt (len .EnumDefinitions) 0 }}
+{{range $Enum := .EnumDefinitions}}
+// Defines values for {{$Enum.TypeName}}.
+const (
+{{range $index, $value := $Enum.Schema.EnumValues}}
+  {{$index}} {{$Enum.TypeName}} = {{$Enum.ValueWrapper}}{{$value}}{{$Enum.ValueWrapper}}
+{{end}}
+)
+{{end}}
+{{end}}
diff --git a/pkg/codegen/templates/templates.gen.go b/pkg/codegen/templates/templates.gen.go
index 6593050..8e652e6 100644
--- a/pkg/codegen/templates/templates.gen.go
+++ b/pkg/codegen/templates/templates.gen.go
@@ -715,6 +715,16 @@ const (
 {{end}}
 )
 {{end}}
+{{if gt (len .EnumDefinitions) 0 }}
+{{range $Enum := .EnumDefinitions}}
+// Defines values for {{$Enum.TypeName}}.
+const (
+{{range $index, $value := $Enum.Schema.EnumValues}}
+  {{$index}} {{$Enum.TypeName}} = {{$Enum.ValueWrapper}}{{$value}}{{$Enum.ValueWrapper}}
+{{end}}
+)
+{{end}}
+{{end}}
 `,
 	"imports.tmpl": `// Package {{.PackageName}} provides primitives to interact with the openapi HTTP API.
 //
@@ -898,15 +908,6 @@ type ServerInterface interface {
 	"typedef.tmpl": `{{range .Types}}
 // {{ with .Schema.Description }}{{ . }}{{ else }}{{.TypeName}} defines model for {{.JsonName}}.{{ end }}
 type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
-{{- if gt (len .Schema.EnumValues) 0 }}
-// List of {{ .TypeName }}
-const (
-	{{- $typeName := .TypeName }}
-    {{- range $key, $value := .Schema.EnumValues }}
-    {{ $typeName }}_{{ $key }} {{ $typeName }} = "{{ $value }}"
-    {{- end }}
-)
-{{- end }}
 {{end}}
 `,
 	"wrappers.tmpl": `// ServerInterfaceWrapper converts echo contexts to parameters.
diff --git a/pkg/codegen/templates/typedef.tmpl b/pkg/codegen/templates/typedef.tmpl
index 422852c..f4596e0 100644
--- a/pkg/codegen/templates/typedef.tmpl
+++ b/pkg/codegen/templates/typedef.tmpl
@@ -1,13 +1,4 @@
 {{range .Types}}
 // {{ with .Schema.Description }}{{ . }}{{ else }}{{.TypeName}} defines model for {{.JsonName}}.{{ end }}
 type {{.TypeName}} {{if and (opts.AliasTypes) (.CanAlias)}}={{end}} {{.Schema.TypeDecl}}
-{{- if gt (len .Schema.EnumValues) 0 }}
-// List of {{ .TypeName }}
-const (
-	{{- $typeName := .TypeName }}
-    {{- range $key, $value := .Schema.EnumValues }}
-    {{ $typeName }}_{{ $key }} {{ $typeName }} = "{{ $value }}"
-    {{- end }}
-)
-{{- end }}
 {{end}}
diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go
index 961d862..0093208 100644
--- a/pkg/codegen/utils.go
+++ b/pkg/codegen/utils.go
@@ -489,7 +489,6 @@ func SanitizeEnumNames(enumNames []string) map[string]string {
 		if _, dup := dupCheck[n]; !dup {
 			deDup = append(deDup, n)
 		}
-
 		dupCheck[n] = 0
 	}
 
@@ -497,14 +496,14 @@ func SanitizeEnumNames(enumNames []string) map[string]string {
 	sanitizedDeDup := make(map[string]string, len(deDup))
 
 	for _, n := range deDup {
-		sanitized := SanitizeGoIdentity(n)
+		sanitized := SchemaNameToTypeName(SanitizeGoIdentity(n))
 
 		if _, dup := dupCheck[sanitized]; !dup {
 			sanitizedDeDup[sanitized] = n
-			dupCheck[sanitized]++
 		} else {
 			sanitizedDeDup[sanitized+strconv.Itoa(dupCheck[sanitized])] = n
 		}
+		dupCheck[sanitized]++
 	}
 
 	return sanitizedDeDup


Test patch:
diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go
index dd30929..cf2787f 100644
--- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go
+++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go
@@ -20,21 +20,28 @@ import (
 	"github.com/labstack/echo/v4"
 )
 
-// Bar defines model for Bar.
-type Bar string
-
-// List of Bar
+// Defines values for Bar.
 const (
-	Bar_Bar      Bar = "Bar"
-	Bar_Foo      Bar = "Foo"
-	Bar_Foo_Bar  Bar = "Foo Bar"
-	Bar_Foo_Bar1 Bar = "Foo-Bar"
-	Bar__Foo     Bar = "1Foo"
-	Bar__Foo1    Bar = " Foo"
-	Bar__Foo_    Bar = " Foo "
-	Bar__Foo_1   Bar = "_Foo_"
+	BarBar Bar = "Bar"
+
+	BarFoo Bar = "Foo"
+
+	BarFoo1 Bar = "1Foo"
+
+	BarFoo2 Bar = " Foo"
+
+	BarFoo3 Bar = " Foo "
+
+	BarFoo4 Bar = "_Foo_"
+
+	BarFooBar Bar = "Foo Bar"
+
+	BarFooBar1 Bar = "Foo-Bar"
 )
 
+// Bar defines model for Bar.
+type Bar string
+
 // RequestEditorFn  is the function signature for the RequestEditor callback function
 type RequestEditorFn func(ctx context.Context, req *http.Request) error
 
diff --git a/internal/test/issues/issue-illegal_enum_names/issue_test.go b/internal/test/issues/issue-illegal_enum_names/issue_test.go
index 9fbd124..617defb 100644
--- a/internal/test/issues/issue-illegal_enum_names/issue_test.go
+++ b/internal/test/issues/issue-illegal_enum_names/issue_test.go
@@ -43,12 +43,12 @@ func TestIllegalEnumNames(t *testing.T) {
 		}
 	}
 
-	require.Equal(t, `"Bar"`, constDefs["Bar_Bar"])
-	require.Equal(t, `"Foo"`, constDefs["Bar_Foo"])
-	require.Equal(t, `"Foo Bar"`, constDefs["Bar_Foo_Bar"])
-	require.Equal(t, `"Foo-Bar"`, constDefs["Bar_Foo_Bar1"])
-	require.Equal(t, `"1Foo"`, constDefs["Bar__Foo"])
-	require.Equal(t, `" Foo"`, constDefs["Bar__Foo1"])
-	require.Equal(t, `" Foo "`, constDefs["Bar__Foo_"])
-	require.Equal(t, `"_Foo_"`, constDefs["Bar__Foo_1"])
+	require.Equal(t, `"Bar"`, constDefs["BarBar"])
+	require.Equal(t, `"Foo"`, constDefs["BarFoo"])
+	require.Equal(t, `"Foo Bar"`, constDefs["BarFooBar"])
+	require.Equal(t, `"Foo-Bar"`, constDefs["BarFooBar1"])
+	require.Equal(t, `"1Foo"`, constDefs["BarFoo1"])
+	require.Equal(t, `" Foo"`, constDefs["BarFoo2"])
+	require.Equal(t, `" Foo "`, constDefs["BarFoo3"])
+	require.Equal(t, `"_Foo_"`, constDefs["BarFoo4"])
 }
diff --git a/internal/test/server/server.gen.go b/internal/test/server/server.gen.go
index 99ec2d0..1b7f034 100644
--- a/internal/test/server/server.gen.go
+++ b/internal/test/server/server.gen.go
@@ -98,6 +98,9 @@ type GetWithArgsParams struct {
 	HeaderArgument *int32 `json:"header_argument,omitempty"`
 }
 
+// GetWithContentTypeParamsContentType defines parameters for GetWithContentType.
+type GetWithContentTypeParamsContentType string
+
 // CreateResourceJSONBody defines parameters for CreateResource.
 type CreateResourceJSONBody EveryTypeRequired
 
@@ -142,7 +145,7 @@ type ServerInterface interface {
 	GetWithReferences(w http.ResponseWriter, r *http.Request, globalArgument int64, argument Argument)
 	// Get an object by ID
 	// (GET /get-with-type/{content_type})
-	GetWithContentType(w http.ResponseWriter, r *http.Request, contentType string)
+	GetWithContentType(w http.ResponseWriter, r *http.Request, contentType GetWithContentTypeParamsContentType)
 	// get with reserved keyword
 	// (GET /reserved-keyword)
 	GetReservedKeyword(w http.ResponseWriter, r *http.Request)
@@ -307,7 +310,7 @@ func (siw *ServerInterfaceWrapper) GetWithContentType(w http.ResponseWriter, r *
 	var err error
 
 	// ------------- Path parameter "content_type" -------------
-	var contentType string
+	var contentType GetWithContentTypeParamsContentType
 
 	err = runtime.BindStyledParameter("simple", false, "content_type", chi.URLParam(r, "content_type"), &contentType)
 	if err != nil {
diff --git a/internal/test/server/server_moq.gen.go b/internal/test/server/server_moq.gen.go
index b3194e7..0cc6afc 100644
--- a/internal/test/server/server_moq.gen.go
+++ b/internal/test/server/server_moq.gen.go
@@ -52,7 +52,7 @@ var _ ServerInterface = &ServerInterfaceMock{}
 //             GetWithArgsFunc: func(w http.ResponseWriter, r *http.Request, params GetWithArgsParams)  {
 // 	               panic("mock out the GetWithArgs method")
 //             },
-//             GetWithContentTypeFunc: func(w http.ResponseWriter, r *http.Request, contentType string)  {
+//             GetWithContentTypeFunc: func(w http.ResponseWriter, r *http.Request, contentType GetWithContentTypeParamsContentType)  {
 // 	               panic("mock out the GetWithContentType method")
 //             },
 //             GetWithReferencesFunc: func(w http.ResponseWriter, r *http.Request, globalArgument int64, argument Argument)  {
@@ -90,7 +90,7 @@ type ServerInterfaceMock struct {
 	GetWithArgsFunc func(w http.ResponseWriter, r *http.Request, params GetWithArgsParams)
 
 	// GetWithContentTypeFunc mocks the GetWithContentType method.
-	GetWithContentTypeFunc func(w http.ResponseWriter, r *http.Request, contentType string)
+	GetWithContentTypeFunc func(w http.ResponseWriter, r *http.Request, contentType GetWithContentTypeParamsContentType)
 
 	// GetWithReferencesFunc mocks the GetWithReferences method.
 	GetWithReferencesFunc func(w http.ResponseWriter, r *http.Request, globalArgument int64, argument Argument)
@@ -164,7 +164,7 @@ type ServerInterfaceMock struct {
 			// R is the r argument value.
 			R *http.Request
 			// ContentType is the contentType argument value.
-			ContentType string
+			ContentType GetWithContentTypeParamsContentType
 		}
 		// GetWithReferences holds details about calls to the GetWithReferences method.
 		GetWithReferences []struct {
@@ -451,14 +451,14 @@ func (mock *ServerInterfaceMock) GetWithArgsCalls() []struct {
 }
 
 // GetWithContentType calls GetWithContentTypeFunc.
-func (mock *ServerInterfaceMock) GetWithContentType(w http.ResponseWriter, r *http.Request, contentType string) {
+func (mock *ServerInterfaceMock) GetWithContentType(w http.ResponseWriter, r *http.Request, contentType GetWithContentTypeParamsContentType) {
 	if mock.GetWithContentTypeFunc == nil {
 		panic("ServerInterfaceMock.GetWithContentTypeFunc: method is nil but ServerInterface.GetWithContentType was just called")
 	}
 	callInfo := struct {
 		W           http.ResponseWriter
 		R           *http.Request
-		ContentType string
+		ContentType GetWithContentTypeParamsContentType
 	}{
 		W:           w,
 		R:           r,
@@ -476,12 +476,12 @@ func (mock *ServerInterfaceMock) GetWithContentType(w http.ResponseWriter, r *ht
 func (mock *ServerInterfaceMock) GetWithContentTypeCalls() []struct {
 	W           http.ResponseWriter
 	R           *http.Request
-	ContentType string
+	ContentType GetWithContentTypeParamsContentType
 } {
 	var calls []struct {
 		W           http.ResponseWriter
 		R           *http.Request
-		ContentType string
+		ContentType GetWithContentTypeParamsContentType
 	}
 	lockServerInterfaceMockGetWithContentType.RLock()
 	calls = mock.calls.GetWithContentType