Skip to content
Closed
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
58 changes: 58 additions & 0 deletions pkg/codegen/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package codegen

import (
"fmt"
"regexp"
"sort"
"strings"

"github.com/getkin/kin-openapi/openapi3"
Expand All @@ -13,10 +15,14 @@ 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

IsExternal bool // Whether it was defined externally, i.e. "x-go-type"
Validations Validations

ArrayType *Schema // The schema of array element

EnumValues map[string]string // Enum values

EmbeddedFields []string // For an allOf struct
Properties []Property // For an object, the fields with names
HasAdditionalProperties bool // Whether we support additional properties
AdditionalPropertiesType *Schema // And if we do, their type
Expand All @@ -27,6 +33,30 @@ type Schema struct {
Description string // The description of the element
}

// Validations describes validations for a schema.
type Validations struct {
// String
MinLength uint64
MaxLength *uint64
Pattern string
Values []string

// Number
Min *float64
ExclusiveMin bool
Max *float64
ExclusiveMax bool
MultipleOf *float64

// Array
MinItems uint64
MaxItems *uint64

// Additional Properties
MinProps uint64
MaxProps *uint64
}

func (s Schema) IsRef() bool {
return s.RefType != ""
}
Expand Down Expand Up @@ -194,6 +224,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
return outSchema, errors.Wrapf(err, "invalid value for %q", extPropGoType)
}
outSchema.GoType = typeName
outSchema.IsExternal = true
return outSchema, nil
}

Expand Down Expand Up @@ -269,6 +300,9 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
return Schema{}, errors.Wrap(err, "error generating type for additional properties")
}
outSchema.AdditionalPropertiesType = &additionalSchema
// Validation rules:
outSchema.Validations.MinProps = schema.MinProps
outSchema.Validations.MaxProps = schema.MaxProps
}

outSchema.GoType = GenStructFromSchema(outSchema)
Expand Down Expand Up @@ -306,6 +340,12 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
outSchema.RefType = typeName
}
//outSchema.RefType = typeName

outSchema.Validations.Values = make([]string, 0, len(outSchema.EnumValues))
for _, value := range outSchema.EnumValues {
outSchema.Validations.Values = append(outSchema.Validations.Values, value)
}
sort.Sort(sort.StringSlice(outSchema.Validations.Values))
} else {
err := resolveType(schema, path, &outSchema)
if err != nil {
Expand Down Expand Up @@ -336,6 +376,8 @@ func resolveType(schema *openapi3.Schema, path []string, outSchema *Schema) erro
outSchema.AdditionalTypes = append(outSchema.AdditionalTypes, additionalTypes...)
}
outSchema.Properties = arrayType.Properties
outSchema.Validations.MinItems = schema.MinItems
outSchema.Validations.MaxItems = schema.MaxItems
case "integer":
// We default to int if format doesn't ask for something else.
if f == "int64" {
Expand All @@ -351,6 +393,11 @@ func resolveType(schema *openapi3.Schema, path []string, outSchema *Schema) erro
} else {
return fmt.Errorf("invalid integer format: %s", f)
}
outSchema.Validations.Min = schema.Min
outSchema.Validations.ExclusiveMin = schema.ExclusiveMin
outSchema.Validations.Max = schema.Max
outSchema.Validations.ExclusiveMax = schema.ExclusiveMax
outSchema.Validations.MultipleOf = schema.MultipleOf
case "number":
// We default to float for "number"
if f == "double" {
Expand All @@ -360,6 +407,8 @@ func resolveType(schema *openapi3.Schema, path []string, outSchema *Schema) erro
} else {
return fmt.Errorf("invalid number format: %s", f)
}
outSchema.Validations.Min = schema.Min
outSchema.Validations.Max = schema.Max
case "boolean":
if f != "" {
return fmt.Errorf("invalid format (%s) for boolean", f)
Expand All @@ -382,6 +431,14 @@ func resolveType(schema *openapi3.Schema, path []string, outSchema *Schema) erro
default:
// All unrecognized formats are simply a regular string.
outSchema.GoType = "string"
outSchema.Validations.MinLength = schema.MinLength
outSchema.Validations.MaxLength = schema.MaxLength
if schema.Pattern != "" {
// Try to compile it first
if _, err := regexp.Compile(schema.Pattern); err == nil {
outSchema.Validations.Pattern = schema.Pattern
}
}
}
default:
return fmt.Errorf("unhandled Schema type: %s", t)
Expand Down Expand Up @@ -468,6 +525,7 @@ func MergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) {
if err != nil {
return Schema{}, errors.Wrap(err, "error converting reference path to a go type")
}
outSchema.EmbeddedFields = append(outSchema.EmbeddedFields, refType)
}

schema, err := GenerateGoSchema(schemaOrRef, path)
Expand Down