From 7eedfa692e426c06fc7f5e4d95ffcc8046aa93a1 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Wed, 8 Nov 2023 01:22:24 +0100 Subject: [PATCH 01/16] feat: implement support for sub-schemas - fix: add guard against loading non-json files when reading references in schemas - feat: introduce basic allOf support - fix: handle struct slices prop merging for allOf types - feat: introduce basic anyOf support, fix default value issue. - fix: make anyOf properties of primitive types dump interface instead of first type - fix: reduce duplicate types - fix: furhter reduce duplicate types - chore: refactor cmp Opts utility - fix: add graceful handling of some edge cases in code generation - empty enum type name - missing unmarshal methods for map types - "Plain" type naming collisions - schema.Type new properties potential (de)serialization - chore: rename test files after rebase - chore: cleanup go deps - chore: fix go linting issues - chore: integrate new formatter changes after rebase - fix: set consistent var names in unmarshallers, introduce support for both yaml and json in validators - chore: remove dead code - fix: use '>' instead of '>=' to perform max length validation. - chore: remove 'two' constant - chore: disable gomnd linter --- .rules/.golangci.yml | 2 + go.mod | 2 + go.sum | 3 + go.work.sum | 1 + internal/x/text/cases.go | 4 + pkg/cmputil/opts.go | 16 + pkg/codegen/model.go | 8 +- pkg/generator/formatter.go | 2 +- pkg/generator/generate.go | 17 +- pkg/generator/json_formatter.go | 34 +- pkg/generator/output.go | 35 ++ pkg/generator/schema_generator.go | 163 ++++--- pkg/generator/utils.go | 2 +- pkg/generator/validator.go | 114 ++++- pkg/generator/yaml_formatter.go | 28 +- pkg/schemas/model.go | 115 ++++- pkg/schemas/types.go | 14 + tests/data/core/allOf/allOf.go | 62 +++ tests/data/core/allOf/allOf.json | 36 ++ tests/data/core/anyOf/anyOf.go | 206 +++++++++ tests/data/core/anyOf/anyOf.json | 54 +++ tests/data/core/array/array.go | 34 +- tests/data/core/date/date.go | 25 +- tests/data/core/dateTime/dateTime.go | 25 +- tests/data/core/ip/ip.go | 25 +- tests/data/core/object/object.go | 25 +- .../objectAdditionalProperties.go | 25 +- .../objectPropertiesDefault.go | 399 ++++++++++++++++++ .../objectPropertiesDefault.json | 104 +++++ tests/data/core/primitives/primitives.go | 25 +- tests/data/core/refToEnum/refToEnum.go | 21 + tests/data/core/time/time.go | 25 +- .../extraImports/gopkgYAMLv3/gopkgYAMLv3.go | 6 +- .../specialCharacters/specialCharacters.go | 106 +++-- .../cyclicAndRequired1/cyclicAndRequired1.go | 25 +- tests/data/regressions/issue32/issue32.go | 28 +- tests/data/validation/enum/enum.go | 373 +++++++++++++--- tests/data/validation/maxItems/maxItems.go | 33 +- tests/data/validation/maxLength/maxLength.go | 31 +- tests/data/validation/minItems/minItems.go | 33 +- tests/data/validation/minLength/minLength.go | 31 +- .../validation/minMaxItems/minMaxItems.go | 42 +- .../requiredFields/requiredFields.go | 186 +++++--- .../validation/typed_default/typed_default.go | 30 +- .../typed_default_empty.go | 25 +- .../typed_default_enums.go | 45 +- tests/generation_test.go | 2 +- tests/go.mod | 2 + tests/go.sum | 2 + 49 files changed, 2343 insertions(+), 308 deletions(-) create mode 100644 pkg/cmputil/opts.go create mode 100644 tests/data/core/allOf/allOf.go create mode 100644 tests/data/core/allOf/allOf.json create mode 100644 tests/data/core/anyOf/anyOf.go create mode 100644 tests/data/core/anyOf/anyOf.json create mode 100644 tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go create mode 100644 tests/data/core/objectPropertiesDefault/objectPropertiesDefault.json diff --git a/.rules/.golangci.yml b/.rules/.golangci.yml index 8585d530..548f95bd 100644 --- a/.rules/.golangci.yml +++ b/.rules/.golangci.yml @@ -49,6 +49,8 @@ linters: # unused - exhaustruct - forbidigo + - gomnd + linters-settings: decorder: disable-init-func-first-check: false diff --git a/go.mod b/go.mod index 210c266c..98d02e99 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,9 @@ module github.com/atombender/go-jsonschema go 1.22 require ( + dario.cat/mergo v1.0.0 github.com/goccy/go-yaml v1.11.3 + github.com/google/go-cmp v0.5.9 github.com/mitchellh/go-wordwrap v1.0.1 github.com/pkg/errors v0.9.1 github.com/sanity-io/litter v1.5.5 diff --git a/go.sum b/go.sum index 196cfbe4..38164695 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b h1:XxMZvQZtTXpWMNWK82vdjCLCe7uGMFXdTsJH0v3Hkvw= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -50,4 +52,5 @@ golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.work.sum b/go.work.sum index ee9badfe..5510afad 100644 --- a/go.work.sum +++ b/go.work.sum @@ -11,6 +11,7 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +github.com/atombender/go-jsonschema/tests/data v0.0.0-20231003003002-2b73c089a581/go.mod h1:kLoRQLRVy+GT9/PG2e3u31DPvDmtFEn7pX6FItvbqlA= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= diff --git a/internal/x/text/cases.go b/internal/x/text/cases.go index 6b6fe6ca..5c43ee64 100644 --- a/internal/x/text/cases.go +++ b/internal/x/text/cases.go @@ -52,6 +52,10 @@ func (c *Caser) Identifierize(s string) string { } } + if ident == "" { + return "Undefined" + } + return ident } diff --git a/pkg/cmputil/opts.go b/pkg/cmputil/opts.go new file mode 100644 index 00000000..a9240a0c --- /dev/null +++ b/pkg/cmputil/opts.go @@ -0,0 +1,16 @@ +package cmputil + +import ( + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +func Opts(t ...any) []cmp.Option { + opts := make([]cmp.Option, 0) + + for _, v := range t { + opts = append(opts, cmpopts.IgnoreUnexported(v), cmpopts.IgnoreFields(v, "Ref"), cmpopts.IgnoreFields(v, "AnyOf")) + } + + return opts +} diff --git a/pkg/codegen/model.go b/pkg/codegen/model.go index 9bdf2e96..5af40bd3 100644 --- a/pkg/codegen/model.go +++ b/pkg/codegen/model.go @@ -197,9 +197,10 @@ func (i *Import) Generate(out *Emitter) { // TypeDecl is a "type = ". type TypeDecl struct { - Name string - Type Type - Comment string + Name string + Type Type + Comment string + SchemaType *schemas.Type } func (td *TypeDecl) GetName() string { @@ -315,6 +316,7 @@ func (NullType) Generate(out *Emitter) { type StructType struct { Fields []StructField RequiredJSONFields []string + DefaultValue interface{} } func (StructType) IsNillable() bool { return false } diff --git a/pkg/generator/formatter.go b/pkg/generator/formatter.go index cc1b23ca..82e332db 100644 --- a/pkg/generator/formatter.go +++ b/pkg/generator/formatter.go @@ -7,7 +7,7 @@ import ( type formatter interface { addImport(out *codegen.File) - generate(declType codegen.TypeDecl, validators []validator) func(*codegen.Emitter) + generate(output *output, declType codegen.TypeDecl, validators []validator) func(*codegen.Emitter) enumMarshal(declType codegen.TypeDecl) func(*codegen.Emitter) enumUnmarshal( declType codegen.TypeDecl, diff --git a/pkg/generator/generate.go b/pkg/generator/generate.go index 93669e2d..aca0912d 100644 --- a/pkg/generator/generate.go +++ b/pkg/generator/generate.go @@ -16,6 +16,7 @@ const ( varNamePlainStruct = "plain" varNameRawMap = "raw" interfaceTypeName = "interface{}" + typePlain = "Plain" ) var ( @@ -26,6 +27,7 @@ var ( errMapURIToPackageName = errors.New("unable to map schema URI to Go package name") errExpectedNamedType = errors.New("expected named type") errUnsupportedRefFormat = errors.New("unsupported $ref format") + ErrUnsupportedRefExtension = errors.New("unsupported $ref extension") errConflictSameFile = errors.New("conflict: same file") errDefinitionDoesNotExistInSchema = errors.New("definition does not exist in schema") errCannotGenerateReferencedType = errors.New("cannot generate referenced type") @@ -176,10 +178,7 @@ func (g *Generator) findOutputFileForSchemaID(id string) (*output, error) { return g.beginOutput(id, g.config.DefaultOutputName, g.config.DefaultPackageName) } -func (g *Generator) beginOutput( - id string, - outputName, packageName string, -) (*output, error) { +func (g *Generator) beginOutput(id, outputName, packageName string) (*output, error) { if packageName == "" { return nil, fmt.Errorf("%w: %q", errMapURIToPackageName, id) } @@ -215,9 +214,15 @@ func (g *Generator) beginOutput( } func (g *Generator) makeEnumConstantName(typeName, value string) string { + idv := g.caser.Identifierize(value) + + if len(typeName) == 0 { + return "Enum" + idv + } + if strings.ContainsAny(typeName[len(typeName)-1:], "0123456789") { - return typeName + "_" + g.caser.Identifierize(value) + return typeName + "_" + idv } - return typeName + g.caser.Identifierize(value) + return typeName + idv } diff --git a/pkg/generator/json_formatter.go b/pkg/generator/json_formatter.go index 3c5e193b..1e2728d5 100644 --- a/pkg/generator/json_formatter.go +++ b/pkg/generator/json_formatter.go @@ -1,6 +1,8 @@ package generator import ( + "fmt" + "math" "strings" "github.com/atombender/go-jsonschema/pkg/codegen" @@ -12,29 +14,41 @@ const ( type jsonFormatter struct{} -func (jf *jsonFormatter) generate(declType codegen.TypeDecl, validators []validator) func(*codegen.Emitter) { +func (jf *jsonFormatter) generate( + output *output, + declType codegen.TypeDecl, + validators []validator, +) func(*codegen.Emitter) { return func(out *codegen.Emitter) { out.Commentf("Unmarshal%s implements %s.Unmarshaler.", strings.ToUpper(formatJSON), formatJSON) - out.Printlnf("func (j *%s) Unmarshal%s(b []byte) error {", declType.Name, strings.ToUpper(formatJSON)) + out.Printlnf("func (j *%s) Unmarshal%s(value []byte) error {", declType.Name, strings.ToUpper(formatJSON)) out.Indent(1) out.Printlnf("var %s map[string]interface{}", varNameRawMap) - out.Printlnf("if err := %s.Unmarshal(b, &%s); err != nil { return err }", + out.Printlnf("if err := %s.Unmarshal(value, &%s); err != nil { return err }", formatJSON, varNameRawMap) for _, v := range validators { - if v.desc().beforeJSONUnmarshal { - v.generate(out) + if v.desc().beforeUnmarshal { + v.generate(out, "json") + } + } + + tp := typePlain + + if tp == declType.Name { + for i := 0; !output.isUniqueTypeName(tp) && i < math.MaxInt; i++ { + tp = fmt.Sprintf("%s_%d", typePlain, i) } } - out.Printlnf("type Plain %s", declType.Name) - out.Printlnf("var %s Plain", varNamePlainStruct) - out.Printlnf("if err := %s.Unmarshal(b, &%s); err != nil { return err }", + out.Printlnf("type %s %s", tp, declType.Name) + out.Printlnf("var %s %s", varNamePlainStruct, tp) + out.Printlnf("if err := %s.Unmarshal(value, &%s); err != nil { return err }", formatJSON, varNamePlainStruct) for _, v := range validators { - if !v.desc().beforeJSONUnmarshal { - v.generate(out) + if !v.desc().beforeUnmarshal { + v.generate(out, "json") } } diff --git a/pkg/generator/output.go b/pkg/generator/output.go index fe0b8de1..d00ea806 100644 --- a/pkg/generator/output.go +++ b/pkg/generator/output.go @@ -3,6 +3,9 @@ package generator import ( "fmt" + "github.com/google/go-cmp/cmp" + + "github.com/atombender/go-jsonschema/pkg/cmputil" "github.com/atombender/go-jsonschema/pkg/codegen" "github.com/atombender/go-jsonschema/pkg/schemas" ) @@ -14,6 +17,38 @@ type output struct { warner func(string) } +func (o *output) getDeclByEqualSchema(name string, t *schemas.Type) *codegen.TypeDecl { + v, ok := o.declsByName[name] + if !ok { + o.warner(fmt.Sprintf("Name not found: %s", name)) + + return nil + } + + if cmp.Equal(v.SchemaType, t, cmputil.Opts(*v.SchemaType, *t)...) { + return v + } + + for count := 1; ; count++ { + suffixed := fmt.Sprintf("%s_%d", name, count) + + sv, ok := o.declsByName[suffixed] + if !ok { + return nil + } + + if cmp.Equal(sv.SchemaType, t, cmputil.Opts(*sv.SchemaType, *t)...) { + return sv + } + } +} + +func (o *output) isUniqueTypeName(name string) bool { + v, ok := o.declsByName[name] + + return !ok || (ok && v.Type == nil) +} + func (o *output) uniqueTypeName(name string) string { v, ok := o.declsByName[name] diff --git a/pkg/generator/schema_generator.go b/pkg/generator/schema_generator.go index bf48eddb..ab46545c 100644 --- a/pkg/generator/schema_generator.go +++ b/pkg/generator/schema_generator.go @@ -5,6 +5,9 @@ import ( "fmt" "strings" + "github.com/google/go-cmp/cmp" + + "github.com/atombender/go-jsonschema/pkg/cmputil" "github.com/atombender/go-jsonschema/pkg/codegen" "github.com/atombender/go-jsonschema/pkg/schemas" ) @@ -202,20 +205,35 @@ func (g *schemaGenerator) generateReferencedType(ref string) (codegen.Type, erro }, nil } -func (g *schemaGenerator) generateDeclaredType( - t *schemas.Type, scope nameScope, -) (codegen.Type, error) { +func (g *schemaGenerator) generateDeclaredType(t *schemas.Type, scope nameScope) (codegen.Type, error) { if decl, ok := g.output.declsBySchema[t]; ok { return &codegen.NamedType{Decl: decl}, nil } + if !g.output.isUniqueTypeName(scope.string()) { + odecl := g.output.declsByName[scope.string()] + + if cmp.Equal(odecl.SchemaType, t, cmputil.Opts(*odecl.SchemaType, *t)...) { + return &codegen.NamedType{Decl: odecl}, nil + } + + if odecl := g.output.declsBySchema[t]; odecl != nil { + return &codegen.NamedType{Decl: odecl}, nil + } + + if odecl := g.output.getDeclByEqualSchema(scope.string(), t); odecl != nil { + return &codegen.NamedType{Decl: odecl}, nil + } + } + if t.Enum != nil { return g.generateEnumType(t, scope) } decl := codegen.TypeDecl{ - Name: g.output.uniqueTypeName(scope.string()), - Comment: t.Description, + Name: g.output.uniqueTypeName(scope.string()), + Comment: t.Description, + SchemaType: t, } g.output.declsBySchema[t] = &decl g.output.declsByName[decl.Name] = &decl @@ -243,6 +261,15 @@ func (g *schemaGenerator) generateDeclaredType( if structType, ok := theType.(*codegen.StructType); ok { var validators []validator + + if t.GetSubSchemaType() == schemas.SubSchemaTypeAnyOf { + validators = append(validators, &anyOfValidator{decl.Name, t.GetSubSchemasCount()}) + + g.generateUnmarshaler(decl, validators) + + return &codegen.NamedType{Decl: &decl}, nil + } + for _, f := range structType.RequiredJSONFields { validators = append(validators, &requiredValidator{f, decl.Name}) } @@ -260,23 +287,16 @@ func (g *schemaGenerator) generateDeclaredType( validators = g.structFieldValidators(validators, f, f.Type, false) } - if len(validators) > 0 { - for _, v := range validators { - if v.desc().hasError { - g.output.file.Package.AddImport("fmt", "") - - break - } - } + if t.IsSubSchemaTypeElem() || len(validators) > 0 { + g.generateUnmarshaler(decl, validators) + } - for _, formatter := range g.formatters { - formatter.addImport(g.output.file) + return &codegen.NamedType{Decl: &decl}, nil + } - g.output.file.Package.AddDecl(&codegen.Method{ - Impl: formatter.generate(decl, validators), - Name: decl.GetName() + "_validator", - }) - } + if _, ok := theType.(*codegen.MapType); ok { + if t.IsSubSchemaTypeElem() { + g.generateUnmarshaler(decl, []validator{}) } } @@ -341,16 +361,38 @@ func (g *schemaGenerator) structFieldValidators( return validators } -func (g *schemaGenerator) generateType( - t *schemas.Type, - scope nameScope, -) (codegen.Type, error) { +func (g *schemaGenerator) generateUnmarshaler(decl codegen.TypeDecl, validators []validator) { + if g.config.OnlyModels { + return + } + + for _, v := range validators { + if _, ok := v.(*anyOfValidator); ok { + g.output.file.Package.AddImport("errors", "") + } + + if v.desc().hasError { + g.output.file.Package.AddImport("fmt", "") + + break + } + } + + for _, formatter := range g.formatters { + formatter.addImport(g.output.file) + + g.output.file.Package.AddDecl(&codegen.Method{ + Impl: formatter.generate(g.output, decl, validators), + Name: decl.GetName() + "_validator", + }) + } +} + +func (g *schemaGenerator) generateType(t *schemas.Type, scope nameScope) (codegen.Type, error) { typeIndex := 0 var typeShouldBePointer bool - two := 2 - if ext := t.GoJSONSchemaExtension; ext != nil { for _, pkg := range ext.Imports { g.output.file.Package.AddImport(pkg, "") @@ -373,7 +415,7 @@ func (g *schemaGenerator) generateType( return codegen.EmptyInterfaceType{}, nil } - if len(t.Type) == two { + if len(t.Type) == 2 { for i, t := range t.Type { if t == "null" { typeShouldBePointer = true @@ -427,10 +469,7 @@ func (g *schemaGenerator) generateType( } } -func (g *schemaGenerator) generateStructType( - t *schemas.Type, - scope nameScope, -) (codegen.Type, error) { +func (g *schemaGenerator) generateStructType(t *schemas.Type, scope nameScope) (codegen.Type, error) { if len(t.Properties) == 0 { if len(t.Required) > 0 { g.warner("Object type with no properties has required fields; " + @@ -442,7 +481,7 @@ func (g *schemaGenerator) generateStructType( var err error if t.AdditionalProperties != nil { - if valueType, err = g.generateType(t.AdditionalProperties, nil); err != nil { + if valueType, err = g.generateType(t.AdditionalProperties, scope.add("Value")); err != nil { return nil, err } } @@ -462,7 +501,7 @@ func (g *schemaGenerator) generateStructType( var structType codegen.StructType - for _, name := range sortPropertiesByName(t.Properties) { + for _, name := range sortedKeys(t.Properties) { prop := t.Properties[name] isRequired := requiredNames[name] @@ -602,19 +641,23 @@ func (g *schemaGenerator) generateStructType( ) } + if t.Default != nil { + structType.DefaultValue = g.defaultPropertyValue(t) + } + return &structType, nil } func (g *schemaGenerator) defaultPropertyValue(prop *schemas.Type) any { if prop.AdditionalProperties != nil { if len(prop.AdditionalProperties.Type) == 0 { - return map[string]any{} + return prop.Default } if len(prop.AdditionalProperties.Type) != 1 { g.warner("Additional property has multiple types; will be represented as an empty interface with no validation") - return map[string]any{} + return prop.Default } switch prop.AdditionalProperties.Type[0] { @@ -634,19 +677,14 @@ func (g *schemaGenerator) defaultPropertyValue(prop *schemas.Type) any { return map[string]bool{} default: - return map[string]any{} + return prop.Default } } return prop.Default } -func (g *schemaGenerator) generateTypeInline( - t *schemas.Type, - scope nameScope, -) (codegen.Type, error) { - two := 2 - +func (g *schemaGenerator) generateTypeInline(t *schemas.Type, scope nameScope) (codegen.Type, error) { if t.Enum == nil && t.Ref == "" { if ext := t.GoJSONSchemaExtension; ext != nil { for _, pkg := range ext.Imports { @@ -658,11 +696,37 @@ func (g *schemaGenerator) generateTypeInline( } } + if len(t.AnyOf) > 0 { + for i, typ := range t.AnyOf { + typ.SetSubSchemaTypeElem() + + if _, err := g.generateTypeInline(typ, scope.add(fmt.Sprintf("_%d", i))); err != nil { + return nil, err + } + } + + anyOfType, err := schemas.AnyOf(t.AnyOf) + if err != nil { + return nil, fmt.Errorf("could not merge anyOf types: %w", err) + } + + return g.generateTypeInline(anyOfType, scope) + } + + if len(t.AllOf) > 0 { + allOfType, err := schemas.AllOf(t.AllOf) + if err != nil { + return nil, fmt.Errorf("could not merge allOf types: %w", err) + } + + return g.generateTypeInline(allOfType, scope) + } + typeIndex := 0 var typeShouldBePointer bool - if len(t.Type) == two { + if len(t.Type) == 2 { for i, t := range t.Type { if t == "null" { typeShouldBePointer = true @@ -685,6 +749,10 @@ func (g *schemaGenerator) generateTypeInline( } if schemas.IsPrimitiveType(t.Type[typeIndex]) { + if t.IsSubSchemaTypeElem() { + return nil, nil + } + cg, err := codegen.PrimitiveTypeFromJSONSchemaType(t.Type[typeIndex], t.Format, typeShouldBePointer) if err != nil { return nil, fmt.Errorf("invalid type %q: %w", t.Type[typeIndex], err) @@ -722,9 +790,7 @@ func (g *schemaGenerator) generateTypeInline( return g.generateDeclaredType(t, scope) } -func (g *schemaGenerator) generateEnumType( - t *schemas.Type, scope nameScope, -) (codegen.Type, error) { +func (g *schemaGenerator) generateEnumType(t *schemas.Type, scope nameScope) (codegen.Type, error) { if len(t.Enum) == 0 { return nil, errEnumArrCannotBeEmpty } @@ -812,8 +878,9 @@ func (g *schemaGenerator) generateEnumType( } enumDecl := codegen.TypeDecl{ - Name: g.output.uniqueTypeName(scope.string()), - Type: enumType, + Name: g.output.uniqueTypeName(scope.string()), + Type: enumType, + SchemaType: t, } g.output.file.Package.AddDecl(&enumDecl) diff --git a/pkg/generator/utils.go b/pkg/generator/utils.go index 77aff3e1..07180923 100644 --- a/pkg/generator/utils.go +++ b/pkg/generator/utils.go @@ -7,7 +7,7 @@ import ( "github.com/atombender/go-jsonschema/pkg/schemas" ) -func sortPropertiesByName(props map[string]*schemas.Type) []string { +func sortedKeys[T any](props map[string]T) []string { names := make([]string, 0, len(props)) for name := range props { names = append(names, name) diff --git a/pkg/generator/validator.go b/pkg/generator/validator.go index 31f09309..10b8ddc9 100644 --- a/pkg/generator/validator.go +++ b/pkg/generator/validator.go @@ -12,13 +12,13 @@ import ( ) type validator interface { - generate(out *codegen.Emitter) + generate(out *codegen.Emitter, format string) desc() *validatorDesc } type validatorDesc struct { - hasError bool - beforeJSONUnmarshal bool + hasError bool + beforeUnmarshal bool } var ( @@ -27,6 +27,7 @@ var ( _ validator = new(defaultValidator) _ validator = new(arrayValidator) _ validator = new(stringValidator) + _ validator = new(anyOfValidator) ) type requiredValidator struct { @@ -34,7 +35,7 @@ type requiredValidator struct { declName string } -func (v *requiredValidator) generate(out *codegen.Emitter) { +func (v *requiredValidator) generate(out *codegen.Emitter, format string) { // The container itself may be null (if the type is ["null", "object"]), in which case // the map will be nil and none of the properties are present. This shouldn't fail // the validation, though, as that's allowed as long as the container is allowed to be null. @@ -47,8 +48,8 @@ func (v *requiredValidator) generate(out *codegen.Emitter) { func (v *requiredValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeJSONUnmarshal: true, + hasError: true, + beforeUnmarshal: true, } } @@ -58,7 +59,7 @@ type nullTypeValidator struct { arrayDepth int } -func (v *nullTypeValidator) generate(out *codegen.Emitter) { +func (v *nullTypeValidator) generate(out *codegen.Emitter, format string) { value := fmt.Sprintf("%s.%s", varNamePlainStruct, v.fieldName) fieldName := v.jsonName @@ -93,8 +94,8 @@ func (v *nullTypeValidator) generate(out *codegen.Emitter) { func (v *nullTypeValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeJSONUnmarshal: false, + hasError: true, + beforeUnmarshal: false, } } @@ -105,12 +106,8 @@ type defaultValidator struct { defaultValue interface{} } -func (v *defaultValidator) generate(out *codegen.Emitter) { - defaultValue, err := v.tryDumpDefaultSlice(out.MaxLineLength()) - if err != nil { - // Fallback to sdump in case we couldn't dump it properly. - defaultValue = litter.Sdump(v.defaultValue) - } +func (v *defaultValidator) generate(out *codegen.Emitter, format string) { + defaultValue := v.dumpDefaultValue(out) out.Printlnf(`if v, ok := %s["%s"]; !ok || v == nil {`, varNameRawMap, v.jsonName) out.Indent(1) @@ -119,6 +116,30 @@ func (v *defaultValidator) generate(out *codegen.Emitter) { out.Printlnf("}") } +func (v *defaultValidator) dumpDefaultValue(out *codegen.Emitter) any { + nt, ok := v.defaultValueType.(*codegen.NamedType) + if v.defaultValueType != nil && ok { + dvm, ok := v.defaultValue.(map[string]any) + if ok { + namedFields := "" + for _, k := range sortedKeys(dvm) { + namedFields += fmt.Sprintf("\n%s: %s,", upperFirst(k), litter.Sdump(dvm[k])) + } + + namedFields += "\n" + + return fmt.Sprintf(`%s{%s}`, nt.Decl.GetName(), namedFields) + } + } + + if defaultValue, err := v.tryDumpDefaultSlice(out.MaxLineLength()); err == nil { + return defaultValue + } + + // Fallback to sdump in case we couldn't dump it properly. + return litter.Sdump(v.defaultValue) +} + func (v *defaultValidator) tryDumpDefaultSlice(maxLineLen uint) (string, error) { tmpEmitter := codegen.NewEmitter(maxLineLen) v.defaultValueType.Generate(tmpEmitter) @@ -147,8 +168,8 @@ func (v *defaultValidator) tryDumpDefaultSlice(maxLineLen uint) (string, error) func (v *defaultValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: false, - beforeJSONUnmarshal: false, + hasError: false, + beforeUnmarshal: false, } } @@ -160,7 +181,7 @@ type arrayValidator struct { maxItems int } -func (v *arrayValidator) generate(out *codegen.Emitter) { +func (v *arrayValidator) generate(out *codegen.Emitter, format string) { if v.minItems == 0 && v.maxItems == 0 { return } @@ -209,8 +230,8 @@ func (v *arrayValidator) generate(out *codegen.Emitter) { func (v *arrayValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeJSONUnmarshal: false, + hasError: true, + beforeUnmarshal: false, } } @@ -222,7 +243,7 @@ type stringValidator struct { isNillable bool } -func (v *stringValidator) generate(out *codegen.Emitter) { +func (v *stringValidator) generate(out *codegen.Emitter, format string) { if v.minLength == 0 && v.maxLength == 0 { return } @@ -257,7 +278,54 @@ func (v *stringValidator) generate(out *codegen.Emitter) { func (v *stringValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeJSONUnmarshal: false, + hasError: true, + beforeUnmarshal: false, + } +} + +type anyOfValidator struct { + fieldName string + elemCount int +} + +func (v *anyOfValidator) generate(out *codegen.Emitter, format string) { + for i := 0; i < v.elemCount; i++ { + out.Printlnf(`var %s_%d %s_%d`, lowerFirst(v.fieldName), i, upperFirst(v.fieldName), i) + } + + out.Printlnf(`var errs []error`) + + for i := 0; i < v.elemCount; i++ { + out.Printlnf( + `if err := %s_%d.Unmarshal%s(value); err != nil {`, + lowerFirst(v.fieldName), + i, + strings.ToUpper(format), + ) + out.Indent(1) + out.Printlnf(`errs = append(errs, err)`) + out.Indent(-1) + out.Printlnf(`}`) + } + + out.Printlnf("if len(errs) == %d {", v.elemCount) + out.Indent(1) + out.Printlnf(`return fmt.Errorf("all validators failed: %%s", errors.Join(errs...))`) + out.Indent(-1) + out.Printlnf("}") +} + +func (v *anyOfValidator) desc() *validatorDesc { + return &validatorDesc{ + hasError: true, + beforeUnmarshal: true, } } + +func lowerFirst(s string) string { + return strings.ToLower(s[:1]) + s[1:] +} + +func upperFirst(s string) string { + return strings.ToUpper(s[:1]) + s[1:] +} diff --git a/pkg/generator/yaml_formatter.go b/pkg/generator/yaml_formatter.go index aff67bb6..017eed74 100644 --- a/pkg/generator/yaml_formatter.go +++ b/pkg/generator/yaml_formatter.go @@ -1,6 +1,8 @@ package generator import ( + "fmt" + "math" "strings" "github.com/atombender/go-jsonschema/pkg/codegen" @@ -13,7 +15,11 @@ const ( type yamlFormatter struct{} -func (yf *yamlFormatter) generate(declType codegen.TypeDecl, validators []validator) func(*codegen.Emitter) { +func (yf *yamlFormatter) generate( + output *output, + declType codegen.TypeDecl, + validators []validator, +) func(*codegen.Emitter) { return func(out *codegen.Emitter) { out.Commentf("Unmarshal%s implements %s.Unmarshaler.", strings.ToUpper(formatYAML), formatYAML) out.Printlnf("func (j *%s) Unmarshal%s(value *yaml.Node) error {", declType.Name, @@ -23,18 +29,26 @@ func (yf *yamlFormatter) generate(declType codegen.TypeDecl, validators []valida out.Printlnf("if err := value.Decode(&%s); err != nil { return err }", varNameRawMap) for _, v := range validators { - if v.desc().beforeJSONUnmarshal { - v.generate(out) + if v.desc().beforeUnmarshal { + v.generate(out, "yaml") + } + } + + tp := typePlain + + if tp == declType.Name { + for i := 0; !output.isUniqueTypeName(tp) && i < math.MaxInt; i++ { + tp = fmt.Sprintf("%s_%d", typePlain, i) } } - out.Printlnf("type Plain %s", declType.Name) - out.Printlnf("var %s Plain", varNamePlainStruct) + out.Printlnf("type %s %s", tp, declType.Name) + out.Printlnf("var %s %s", varNamePlainStruct, tp) out.Printlnf("if err := value.Decode(&%s); err != nil { return err }", varNamePlainStruct) for _, v := range validators { - if !v.desc().beforeJSONUnmarshal { - v.generate(out) + if !v.desc().beforeUnmarshal { + v.generate(out, "yaml") } } diff --git a/pkg/schemas/model.go b/pkg/schemas/model.go index a85c990e..fecf6d74 100644 --- a/pkg/schemas/model.go +++ b/pkg/schemas/model.go @@ -26,6 +26,14 @@ package schemas import ( "encoding/json" "fmt" + "reflect" + + "dario.cat/mergo" +) + +var ( + ErrCannotMergeTypes = fmt.Errorf("cannot merge types") + ErrEmptyTypesList = fmt.Errorf("types list is empty") ) // Schema is the root schema. @@ -106,6 +114,15 @@ func (t *TypeList) UnmarshalJSON(b []byte) error { // RFC draft-wright-json-schema-validation-00, section 5.26. type Definitions map[string]*Type +type SubSchemaType string + +const ( + SubSchemaTypeAllOf SubSchemaType = "allOf" + SubSchemaTypeAnyOf SubSchemaType = "anyOf" + SubSchemaTypeOneOf SubSchemaType = "oneOf" + SubSchemaTypeNot SubSchemaType = "not" +) + // Type represents a JSON Schema object type. type Type struct { // RFC draft-wright-json-schema-00. @@ -133,10 +150,11 @@ type Type struct { AdditionalProperties *Type `json:"additionalProperties,omitempty"` // Section 5.18. Enum []interface{} `json:"enum,omitempty"` // Section 5.20. Type TypeList `json:"type,omitempty"` // Section 5.21. - AllOf []*Type `json:"allOf,omitempty"` // Section 5.22. - AnyOf []*Type `json:"anyOf,omitempty"` // Section 5.23. - OneOf []*Type `json:"oneOf,omitempty"` // Section 5.24. - Not *Type `json:"not,omitempty"` // Section 5.25. + // RFC draft-bhutton-json-schema-01, section 10. + AllOf []*Type `json:"allOf,omitempty"` // Section 10.2.1.1. + AnyOf []*Type `json:"anyOf,omitempty"` // Section 10.2.1.2. + OneOf []*Type `json:"oneOf,omitempty"` // Section 10.2.1.3. + Not *Type `json:"not,omitempty"` // Section 10.2.1.4. // RFC draft-wright-json-schema-validation-00, section 6, 7. Title string `json:"title,omitempty"` // Section 6.1. Description string `json:"description,omitempty"` // Section 6.1. @@ -154,6 +172,35 @@ type Type struct { // ExtGoCustomType is the name of a (qualified or not) custom Go type // to use for the field. GoJSONSchemaExtension *GoJSONSchemaExtension `json:"goJSONSchema,omitempty"` //nolint:tagliatelle // breaking change + + // SubSchemaType marks the type as being a subschema type. + subSchemaType SubSchemaType + subSchemasCount int + subSchemaTypeElem bool +} + +func (value *Type) SetSubSchemaType(sst SubSchemaType) { + value.subSchemaType = sst +} + +func (value *Type) GetSubSchemaType() SubSchemaType { + return value.subSchemaType +} + +func (value *Type) SetSubSchemasCount(ssc int) { + value.subSchemasCount = ssc +} + +func (value *Type) GetSubSchemasCount() int { + return value.subSchemasCount +} + +func (value *Type) IsSubSchemaTypeElem() bool { + return value.subSchemaTypeElem +} + +func (value *Type) SetSubSchemaTypeElem() { + value.subSchemaTypeElem = true } // UnmarshalJSON accepts booleans as schemas where `true` is equivalent to `{}` @@ -198,6 +245,66 @@ func (value *Type) UnmarshalJSON(raw []byte) error { return nil } +func AllOf(types []*Type) (*Type, error) { + typ, err := MergeTypes(types) + if err != nil { + return nil, err + } + + typ.subSchemaType = SubSchemaTypeAllOf + + return typ, nil +} + +func AnyOf(types []*Type) (*Type, error) { + typ, err := MergeTypes(types) + if err != nil { + return nil, err + } + + typ.subSchemaType = SubSchemaTypeAnyOf + typ.subSchemasCount = len(types) + + return typ, nil +} + +func MergeTypes(types []*Type) (*Type, error) { + if len(types) == 0 { + return nil, ErrEmptyTypesList + } + + result := &Type{} + + if isPrimitiveTypeList(types) { + return result, nil + } + + opts := []func(*mergo.Config){ + mergo.WithAppendSlice, + mergo.WithTransformers(typeListTransformer{}), + } + + for _, t := range types { + if err := mergo.Merge(result, t, opts...); err != nil { + return nil, fmt.Errorf("%w: %w", ErrCannotMergeTypes, err) + } + } + + return result, nil +} + +type typeListTransformer struct{} + +func (t typeListTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error { + if typ == reflect.TypeOf(TypeList{}) { + return func(dst, src reflect.Value) error { + return nil + } + } + + return nil +} + type GoJSONSchemaExtension struct { Type *string `json:"type,omitempty"` Identifier *string `json:"identifier,omitempty"` diff --git a/pkg/schemas/types.go b/pkg/schemas/types.go index ad62d4d4..be224f21 100644 --- a/pkg/schemas/types.go +++ b/pkg/schemas/types.go @@ -30,3 +30,17 @@ func CleanNameForSorting(name string) string { return name } + +func isPrimitiveTypeList(types []*Type) bool { + for _, typ := range types { + if len(typ.Type) == 0 { + continue + } + + if !IsPrimitiveType(typ.Type[0]) { + return false + } + } + + return true +} diff --git a/tests/data/core/allOf/allOf.go b/tests/data/core/allOf/allOf.go new file mode 100644 index 00000000..fcd447e0 --- /dev/null +++ b/tests/data/core/allOf/allOf.go @@ -0,0 +1,62 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package test + +import "encoding/json" +import "fmt" +import yaml "gopkg.in/yaml.v3" + +type AllOfConfigurationsElem struct { + // Bar corresponds to the JSON schema field "bar". + Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` + + // Foo corresponds to the JSON schema field "foo". + Foo string `json:"foo" yaml:"foo" mapstructure:"foo"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *AllOfConfigurationsElem) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if v, ok := raw["bar"]; !ok || v == nil { + return fmt.Errorf("field bar in AllOfConfigurationsElem: required") + } + if v, ok := raw["foo"]; !ok || v == nil { + return fmt.Errorf("field foo in AllOfConfigurationsElem: required") + } + type Plain AllOfConfigurationsElem + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = AllOfConfigurationsElem(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AllOfConfigurationsElem) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["bar"]; !ok || v == nil { + return fmt.Errorf("field bar in AllOfConfigurationsElem: required") + } + if v, ok := raw["foo"]; !ok || v == nil { + return fmt.Errorf("field foo in AllOfConfigurationsElem: required") + } + type Plain AllOfConfigurationsElem + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = AllOfConfigurationsElem(plain) + return nil +} + +type AllOf struct { + // Configurations corresponds to the JSON schema field "configurations". + Configurations []AllOfConfigurationsElem `json:"configurations,omitempty" yaml:"configurations,omitempty" mapstructure:"configurations,omitempty"` +} diff --git a/tests/data/core/allOf/allOf.json b/tests/data/core/allOf/allOf.json new file mode 100644 index 00000000..bf6ca62b --- /dev/null +++ b/tests/data/core/allOf/allOf.json @@ -0,0 +1,36 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "id": "https://example.com/objectAllOf", + "type": "object", + "properties": { + "configurations": { + "type": "array", + "items": { + "allOf": [ + { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + }, + "required": [ + "foo" + ] + }, + { + "type": "object", + "properties": { + "bar": { + "type": "number" + } + }, + "required": [ + "bar" + ] + } + ] + } + } + } +} diff --git a/tests/data/core/anyOf/anyOf.go b/tests/data/core/anyOf/anyOf.go new file mode 100644 index 00000000..358396a1 --- /dev/null +++ b/tests/data/core/anyOf/anyOf.go @@ -0,0 +1,206 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package test + +import "encoding/json" +import "errors" +import "fmt" +import yaml "gopkg.in/yaml.v3" + +type AnyOf struct { + // Configurations corresponds to the JSON schema field "configurations". + Configurations []AnyOfConfigurationsElem `json:"configurations,omitempty" yaml:"configurations,omitempty" mapstructure:"configurations,omitempty"` + + // Flags corresponds to the JSON schema field "flags". + Flags interface{} `json:"flags,omitempty" yaml:"flags,omitempty" mapstructure:"flags,omitempty"` +} + +type AnyOfConfigurationsElem struct { + // Bar corresponds to the JSON schema field "bar". + Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` + + // Baz corresponds to the JSON schema field "baz". + Baz *bool `json:"baz,omitempty" yaml:"baz,omitempty" mapstructure:"baz,omitempty"` + + // Foo corresponds to the JSON schema field "foo". + Foo string `json:"foo" yaml:"foo" mapstructure:"foo"` +} + +type AnyOfConfigurationsElem_0 struct { + // Foo corresponds to the JSON schema field "foo". + Foo string `json:"foo" yaml:"foo" mapstructure:"foo"` +} + +type AnyOfConfigurationsElem_1 struct { + // Bar corresponds to the JSON schema field "bar". + Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *AnyOfConfigurationsElem_1) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if v, ok := raw["bar"]; !ok || v == nil { + return fmt.Errorf("field bar in AnyOfConfigurationsElem_1: required") + } + type Plain AnyOfConfigurationsElem_1 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_1(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AnyOfConfigurationsElem_1) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["bar"]; !ok || v == nil { + return fmt.Errorf("field bar in AnyOfConfigurationsElem_1: required") + } + type Plain AnyOfConfigurationsElem_1 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_1(plain) + return nil +} + +type AnyOfConfigurationsElem_2 struct { + // Baz corresponds to the JSON schema field "baz". + Baz *bool `json:"baz,omitempty" yaml:"baz,omitempty" mapstructure:"baz,omitempty"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *AnyOfConfigurationsElem_2) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain AnyOfConfigurationsElem_2 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_2(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AnyOfConfigurationsElem_2) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain AnyOfConfigurationsElem_2 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_2(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AnyOfConfigurationsElem_0) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["foo"]; !ok || v == nil { + return fmt.Errorf("field foo in AnyOfConfigurationsElem_0: required") + } + type Plain AnyOfConfigurationsElem_0 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_0(plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *AnyOfConfigurationsElem) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + var anyOfConfigurationsElem_0 AnyOfConfigurationsElem_0 + var anyOfConfigurationsElem_1 AnyOfConfigurationsElem_1 + var anyOfConfigurationsElem_2 AnyOfConfigurationsElem_2 + var errs []error + if err := anyOfConfigurationsElem_0.UnmarshalJSON(value); err != nil { + errs = append(errs, err) + } + if err := anyOfConfigurationsElem_1.UnmarshalJSON(value); err != nil { + errs = append(errs, err) + } + if err := anyOfConfigurationsElem_2.UnmarshalJSON(value); err != nil { + errs = append(errs, err) + } + if len(errs) == 3 { + return fmt.Errorf("all validators failed: %s", errors.Join(errs...)) + } + type Plain AnyOfConfigurationsElem + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AnyOfConfigurationsElem) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + var anyOfConfigurationsElem_0 AnyOfConfigurationsElem_0 + var anyOfConfigurationsElem_1 AnyOfConfigurationsElem_1 + var anyOfConfigurationsElem_2 AnyOfConfigurationsElem_2 + var errs []error + if err := anyOfConfigurationsElem_0.UnmarshalYAML(value); err != nil { + errs = append(errs, err) + } + if err := anyOfConfigurationsElem_1.UnmarshalYAML(value); err != nil { + errs = append(errs, err) + } + if err := anyOfConfigurationsElem_2.UnmarshalYAML(value); err != nil { + errs = append(errs, err) + } + if len(errs) == 3 { + return fmt.Errorf("all validators failed: %s", errors.Join(errs...)) + } + type Plain AnyOfConfigurationsElem + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem(plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *AnyOfConfigurationsElem_0) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if v, ok := raw["foo"]; !ok || v == nil { + return fmt.Errorf("field foo in AnyOfConfigurationsElem_0: required") + } + type Plain AnyOfConfigurationsElem_0 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_0(plain) + return nil +} diff --git a/tests/data/core/anyOf/anyOf.json b/tests/data/core/anyOf/anyOf.json new file mode 100644 index 00000000..d7433a7f --- /dev/null +++ b/tests/data/core/anyOf/anyOf.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "id": "https://example.com/objectAllOf", + "type": "object", + "properties": { + "flags": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + } + ] + }, + "configurations": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + }, + "required": [ + "foo" + ] + }, + { + "type": "object", + "properties": { + "bar": { + "type": "number" + } + }, + "required": [ + "bar" + ] + }, + { + "type": "object", + "properties": { + "baz": { + "type": "boolean" + } + } + } + ] + } + } + } +} diff --git a/tests/data/core/array/array.go b/tests/data/core/array/array.go index 9b91d96c..c7a83351 100644 --- a/tests/data/core/array/array.go +++ b/tests/data/core/array/array.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Array struct { // MyArray corresponds to the JSON schema field "myArray". @@ -34,14 +35,41 @@ type Array struct { type ArrayMyObjectArrayElem map[string]interface{} // UnmarshalJSON implements json.Unmarshaler. -func (j *Array) UnmarshalJSON(b []byte) error { +func (j *Array) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain Array var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + for i0 := range plain.MyNestedNullArray { + for i1 := range plain.MyNestedNullArray[i0] { + if plain.MyNestedNullArray[i0][i1] != nil { + return fmt.Errorf("field %s: must be null", fmt.Sprintf("myNestedNullArray[%d][%d]", i0, i1)) + } + } + } + for i0 := range plain.MyNullArray { + if plain.MyNullArray[i0] != nil { + return fmt.Errorf("field %s: must be null", fmt.Sprintf("myNullArray[%d]", i0)) + } + } + *j = Array(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Array) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain Array + var plain Plain + if err := value.Decode(&plain); err != nil { return err } for i0 := range plain.MyNestedNullArray { diff --git a/tests/data/core/date/date.go b/tests/data/core/date/date.go index dcf31db6..46f84ee3 100644 --- a/tests/data/core/date/date.go +++ b/tests/data/core/date/date.go @@ -5,6 +5,7 @@ package test import "encoding/json" import "fmt" import "github.com/atombender/go-jsonschema/pkg/types" +import yaml "gopkg.in/yaml.v3" type Date struct { // MyObject corresponds to the JSON schema field "myObject". @@ -17,9 +18,9 @@ type DateMyObject struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *DateMyObject) UnmarshalJSON(b []byte) error { +func (j *DateMyObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myDate"]; raw != nil && !ok { @@ -27,7 +28,25 @@ func (j *DateMyObject) UnmarshalJSON(b []byte) error { } type Plain DateMyObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = DateMyObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *DateMyObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myDate"]; !ok || v == nil { + return fmt.Errorf("field myDate in DateMyObject: required") + } + type Plain DateMyObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = DateMyObject(plain) diff --git a/tests/data/core/dateTime/dateTime.go b/tests/data/core/dateTime/dateTime.go index 271752ed..33b91867 100644 --- a/tests/data/core/dateTime/dateTime.go +++ b/tests/data/core/dateTime/dateTime.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "time" type DateTime struct { @@ -17,9 +18,9 @@ type DateTimeMyObject struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *DateTimeMyObject) UnmarshalJSON(b []byte) error { +func (j *DateTimeMyObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myDateTime"]; raw != nil && !ok { @@ -27,7 +28,25 @@ func (j *DateTimeMyObject) UnmarshalJSON(b []byte) error { } type Plain DateTimeMyObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = DateTimeMyObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *DateTimeMyObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myDateTime"]; !ok || v == nil { + return fmt.Errorf("field myDateTime in DateTimeMyObject: required") + } + type Plain DateTimeMyObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = DateTimeMyObject(plain) diff --git a/tests/data/core/ip/ip.go b/tests/data/core/ip/ip.go index b8d8ea93..cda65d48 100644 --- a/tests/data/core/ip/ip.go +++ b/tests/data/core/ip/ip.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "net/netip" type Ip struct { @@ -17,9 +18,9 @@ type IpMyObject struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *IpMyObject) UnmarshalJSON(b []byte) error { +func (j *IpMyObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myIp"]; raw != nil && !ok { @@ -27,7 +28,25 @@ func (j *IpMyObject) UnmarshalJSON(b []byte) error { } type Plain IpMyObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = IpMyObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *IpMyObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myIp"]; !ok || v == nil { + return fmt.Errorf("field myIp in IpMyObject: required") + } + type Plain IpMyObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = IpMyObject(plain) diff --git a/tests/data/core/object/object.go b/tests/data/core/object/object.go index 83521b77..fd6fd023 100644 --- a/tests/data/core/object/object.go +++ b/tests/data/core/object/object.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Object struct { // MyObject corresponds to the JSON schema field "myObject". @@ -16,9 +17,9 @@ type ObjectMyObject struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ObjectMyObject) UnmarshalJSON(b []byte) error { +func (j *ObjectMyObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myString"]; raw != nil && !ok { @@ -26,7 +27,25 @@ func (j *ObjectMyObject) UnmarshalJSON(b []byte) error { } type Plain ObjectMyObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = ObjectMyObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectMyObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myString"]; !ok || v == nil { + return fmt.Errorf("field myString in ObjectMyObject: required") + } + type Plain ObjectMyObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = ObjectMyObject(plain) diff --git a/tests/data/core/objectAdditionalProperties/objectAdditionalProperties.go b/tests/data/core/objectAdditionalProperties/objectAdditionalProperties.go index 358312c2..d1041f1a 100644 --- a/tests/data/core/objectAdditionalProperties/objectAdditionalProperties.go +++ b/tests/data/core/objectAdditionalProperties/objectAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type ObjectAdditionalProperties struct { // Foo corresponds to the JSON schema field "foo". @@ -12,14 +13,32 @@ type ObjectAdditionalProperties struct { type ObjectAdditionalPropertiesFoo map[string]string // UnmarshalJSON implements json.Unmarshaler. -func (j *ObjectAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *ObjectAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain ObjectAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["foo"]; !ok || v == nil { + plain.Foo = map[string]string{} + } + *j = ObjectAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain ObjectAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw["foo"]; !ok || v == nil { diff --git a/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go new file mode 100644 index 00000000..af6be8c3 --- /dev/null +++ b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go @@ -0,0 +1,399 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package test + +import "encoding/json" +import "errors" +import "fmt" +import yaml "gopkg.in/yaml.v3" +import "reflect" + +type DecoratedPlanner struct { + // Decorator corresponds to the JSON schema field "decorator". + Decorator DecoratedPlannerDecorator `json:"decorator,omitempty" yaml:"decorator,omitempty" mapstructure:"decorator,omitempty"` + + // Event corresponds to the JSON schema field "event". + Event *Event `json:"event,omitempty" yaml:"event,omitempty" mapstructure:"event,omitempty"` +} + +type DecoratedPlannerDecorator struct { + // Color corresponds to the JSON schema field "color". + Color string `json:"color,omitempty" yaml:"color,omitempty" mapstructure:"color,omitempty"` + + // Theme corresponds to the JSON schema field "theme". + Theme *string `json:"theme,omitempty" yaml:"theme,omitempty" mapstructure:"theme,omitempty"` +} + +type DefaultPlanner struct { + // Event corresponds to the JSON schema field "event". + Event *Event `json:"event,omitempty" yaml:"event,omitempty" mapstructure:"event,omitempty"` +} + +type Event struct { + // Name corresponds to the JSON schema field "name". + Name *EventName `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` + + // Tags corresponds to the JSON schema field "tags". + Tags []EventTagsElem `json:"tags,omitempty" yaml:"tags,omitempty" mapstructure:"tags,omitempty"` +} + +type EventName string + +const EventNameBIRTHDAY EventName = "BIRTHDAY" +const EventNameGAME EventName = "GAME" + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *DecoratedPlannerDecorator) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain DecoratedPlannerDecorator + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if v, ok := raw["color"]; !ok || v == nil { + plain.Color = "#ffffff" + } + *j = DecoratedPlannerDecorator(plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *EventName) UnmarshalJSON(b []byte) error { + var v string + if err := json.Unmarshal(b, &v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EventName { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EventName, v) + } + *j = EventName(v) + return nil +} + +const EventNameHOLIDAY EventName = "HOLIDAY" + +type EventTagsElem string + +var enumValues_EventTagsElem = []interface{}{ + "COUNTRY", + "REGION", + "CITY", + "PERSON", +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *EventTagsElem) UnmarshalJSON(b []byte) error { + var v string + if err := json.Unmarshal(b, &v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EventTagsElem { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EventTagsElem, v) + } + *j = EventTagsElem(v) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EventTagsElem) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EventTagsElem { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EventTagsElem, v) + } + *j = EventTagsElem(v) + return nil +} + +const EventTagsElemCOUNTRY EventTagsElem = "COUNTRY" +const EventTagsElemREGION EventTagsElem = "REGION" +const EventTagsElemCITY EventTagsElem = "CITY" +const EventTagsElemPERSON EventTagsElem = "PERSON" + +var enumValues_EventName = []interface{}{ + "BIRTHDAY", + "GAME", + "HOLIDAY", +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *Event) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain Event + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["tags"]; !ok || v == nil { + plain.Tags = []EventTagsElem{} + } + *j = Event(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Event) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain Event + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if v, ok := raw["tags"]; !ok || v == nil { + plain.Tags = []EventTagsElem{} + } + *j = Event(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EventName) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EventName { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EventName, v) + } + *j = EventName(v) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *DecoratedPlanner) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain DecoratedPlanner + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["decorator"]; !ok || v == nil { + plain.Decorator = DecoratedPlannerDecorator{ + Color: "#ffffff", + Theme: nil, + } + } + *j = DecoratedPlanner(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *DecoratedPlanner) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain DecoratedPlanner + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if v, ok := raw["decorator"]; !ok || v == nil { + plain.Decorator = DecoratedPlannerDecorator{ + Color: "#ffffff", + Theme: nil, + } + } + *j = DecoratedPlanner(plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *DecoratedPlannerDecorator) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain DecoratedPlannerDecorator + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["color"]; !ok || v == nil { + plain.Color = "#ffffff" + } + *j = DecoratedPlannerDecorator(plain) + return nil +} + +type ObjectPropertiesDefaultPlannersElem_0 struct { + // Plain corresponds to the JSON schema field "plain". + Plain *DefaultPlanner `json:"plain,omitempty" yaml:"plain,omitempty" mapstructure:"plain,omitempty"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain ObjectPropertiesDefaultPlannersElem_0 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = ObjectPropertiesDefaultPlannersElem_0(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain ObjectPropertiesDefaultPlannersElem_0 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = ObjectPropertiesDefaultPlannersElem_0(plain) + return nil +} + +type ObjectPropertiesDefaultPlannersElem_1 struct { + // Decorated corresponds to the JSON schema field "decorated". + Decorated *DecoratedPlanner `json:"decorated,omitempty" yaml:"decorated,omitempty" mapstructure:"decorated,omitempty"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem_1) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain ObjectPropertiesDefaultPlannersElem_1 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = ObjectPropertiesDefaultPlannersElem_1(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem_1) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain ObjectPropertiesDefaultPlannersElem_1 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = ObjectPropertiesDefaultPlannersElem_1(plain) + return nil +} + +type ObjectPropertiesDefaultPlannersElem struct { + // Decorated corresponds to the JSON schema field "decorated". + Decorated *DecoratedPlanner `json:"decorated,omitempty" yaml:"decorated,omitempty" mapstructure:"decorated,omitempty"` + + // Plain corresponds to the JSON schema field "plain". + Plain *DefaultPlanner `json:"plain,omitempty" yaml:"plain,omitempty" mapstructure:"plain,omitempty"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + var objectPropertiesDefaultPlannersElem_0 ObjectPropertiesDefaultPlannersElem_0 + var objectPropertiesDefaultPlannersElem_1 ObjectPropertiesDefaultPlannersElem_1 + var errs []error + if err := objectPropertiesDefaultPlannersElem_0.UnmarshalJSON(value); err != nil { + errs = append(errs, err) + } + if err := objectPropertiesDefaultPlannersElem_1.UnmarshalJSON(value); err != nil { + errs = append(errs, err) + } + if len(errs) == 2 { + return fmt.Errorf("all validators failed: %s", errors.Join(errs...)) + } + type Plain ObjectPropertiesDefaultPlannersElem + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = ObjectPropertiesDefaultPlannersElem(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + var objectPropertiesDefaultPlannersElem_0 ObjectPropertiesDefaultPlannersElem_0 + var objectPropertiesDefaultPlannersElem_1 ObjectPropertiesDefaultPlannersElem_1 + var errs []error + if err := objectPropertiesDefaultPlannersElem_0.UnmarshalYAML(value); err != nil { + errs = append(errs, err) + } + if err := objectPropertiesDefaultPlannersElem_1.UnmarshalYAML(value); err != nil { + errs = append(errs, err) + } + if len(errs) == 2 { + return fmt.Errorf("all validators failed: %s", errors.Join(errs...)) + } + type Plain ObjectPropertiesDefaultPlannersElem + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = ObjectPropertiesDefaultPlannersElem(plain) + return nil +} + +type ObjectPropertiesDefault struct { + // Active corresponds to the JSON schema field "active". + Active interface{} `json:"active,omitempty" yaml:"active,omitempty" mapstructure:"active,omitempty"` + + // Planners corresponds to the JSON schema field "planners". + Planners []ObjectPropertiesDefaultPlannersElem `json:"planners,omitempty" yaml:"planners,omitempty" mapstructure:"planners,omitempty"` +} diff --git a/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.json b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.json new file mode 100644 index 00000000..aa4b694b --- /dev/null +++ b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.json @@ -0,0 +1,104 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "DecoratedPlanner": { + "type": "object", + "properties": { + "decorator": { + "type": "object", + "properties": { + "color": { + "type": "string", + "default": "#ffffff" + }, + "theme": { + "type": "string" + } + }, + "additionalProperties": false, + "default": { + "theme": null, + "color": "#ffffff" + } + }, + "event": { + "$ref": "#/definitions/Event" + } + }, + "additionalProperties": false + }, + "DefaultPlanner": { + "type": "object", + "properties": { + "event": { + "$ref": "#/definitions/Event" + } + }, + "additionalProperties": false + }, + "Event": { + "type": "object", + "properties": { + "name": { + "type": "string", + "enum": [ + "BIRTHDAY", + "GAME", + "HOLIDAY" + ] + }, + "tags": { + "default": [], + "type": "array", + "items": { + "type": "string", + "enum": [ + "COUNTRY", + "REGION", + "CITY", + "PERSON" + ] + } + } + }, + "additionalProperties": false + } + }, + "type": "object", + "properties": { + "active": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + } + ] + }, + "planners": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "plain": { + "$ref": "#/definitions/DefaultPlanner" + } + } + }, + { + "type": "object", + "properties": { + "decorated": { + "$ref": "#/definitions/DecoratedPlanner" + } + } + } + ] + } + } + }, + "additionalProperties": false +} diff --git a/tests/data/core/primitives/primitives.go b/tests/data/core/primitives/primitives.go index 65671635..78662486 100644 --- a/tests/data/core/primitives/primitives.go +++ b/tests/data/core/primitives/primitives.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Primitives struct { // MyBoolean corresponds to the JSON schema field "myBoolean". @@ -23,14 +24,32 @@ type Primitives struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Primitives) UnmarshalJSON(b []byte) error { +func (j *Primitives) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain Primitives var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyNull != nil { + return fmt.Errorf("field %s: must be null", "myNull") + } + *j = Primitives(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Primitives) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain Primitives + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyNull != nil { diff --git a/tests/data/core/refToEnum/refToEnum.go b/tests/data/core/refToEnum/refToEnum.go index 6331c642..22bb84c3 100644 --- a/tests/data/core/refToEnum/refToEnum.go +++ b/tests/data/core/refToEnum/refToEnum.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "reflect" type RefToEnum struct { @@ -40,3 +41,23 @@ func (j *Thing) UnmarshalJSON(b []byte) error { *j = Thing(v) return nil } + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Thing) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_Thing { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Thing, v) + } + *j = Thing(v) + return nil +} diff --git a/tests/data/core/time/time.go b/tests/data/core/time/time.go index 3182fdfb..c083afe8 100644 --- a/tests/data/core/time/time.go +++ b/tests/data/core/time/time.go @@ -5,6 +5,7 @@ package test import "encoding/json" import "fmt" import "github.com/atombender/go-jsonschema/pkg/types" +import yaml "gopkg.in/yaml.v3" type Time struct { // MyObject corresponds to the JSON schema field "myObject". @@ -17,9 +18,9 @@ type TimeMyObject struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *TimeMyObject) UnmarshalJSON(b []byte) error { +func (j *TimeMyObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myTime"]; raw != nil && !ok { @@ -27,7 +28,25 @@ func (j *TimeMyObject) UnmarshalJSON(b []byte) error { } type Plain TimeMyObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = TimeMyObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *TimeMyObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myTime"]; !ok || v == nil { + return fmt.Errorf("field myTime in TimeMyObject: required") + } + type Plain TimeMyObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = TimeMyObject(plain) diff --git a/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go b/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go index 3d08a51f..895ba3a0 100644 --- a/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go +++ b/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go @@ -78,14 +78,14 @@ func (j *GopkgYAMLv3MyEnum) UnmarshalYAML(value *yaml.Node) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *GopkgYAMLv3) UnmarshalJSON(b []byte) error { +func (j *GopkgYAMLv3) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain GopkgYAMLv3 var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } if plain.MyNull != nil { diff --git a/tests/data/misc/specialCharacters/specialCharacters.go b/tests/data/misc/specialCharacters/specialCharacters.go index 7895d43a..da25bfaa 100644 --- a/tests/data/misc/specialCharacters/specialCharacters.go +++ b/tests/data/misc/specialCharacters/specialCharacters.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "reflect" type License string @@ -11,45 +12,48 @@ type License string const LicenseGPL30 License = "GPL-3.0" const LicenseMIT License = "MIT" -type License_1 string +type SpecialCharacters struct { + // PlainLicenses corresponds to the JSON schema field "plainLicenses". + PlainLicenses *SpecialCharactersPlainLicenses `json:"plainLicenses,omitempty" yaml:"plainLicenses,omitempty" mapstructure:"plainLicenses,omitempty"` -const License_1_GPL30 License_1 = "GPL-3.0+" -const License_1_MIT License_1 = "MIT+" + // PlainLicensesRef corresponds to the JSON schema field "plainLicensesRef". + PlainLicensesRef []License `json:"plainLicensesRef,omitempty" yaml:"plainLicensesRef,omitempty" mapstructure:"plainLicensesRef,omitempty"` -var enumValues_License_1 = []interface{}{ - "GPL-3.0+", - "MIT+", + // PlusLicenses corresponds to the JSON schema field "plusLicenses". + PlusLicenses *SpecialCharactersPlusLicenses `json:"plusLicenses,omitempty" yaml:"plusLicenses,omitempty" mapstructure:"plusLicenses,omitempty"` + + // PlusLicensesRef corresponds to the JSON schema field "plusLicensesRef". + PlusLicensesRef []License `json:"plusLicensesRef,omitempty" yaml:"plusLicensesRef,omitempty" mapstructure:"plusLicensesRef,omitempty"` } +type SpecialCharactersPlainLicenses string + +const SpecialCharactersPlainLicensesGPL30 SpecialCharactersPlainLicenses = "GPL-3.0" + // UnmarshalJSON implements json.Unmarshaler. -func (j *License_1) UnmarshalJSON(b []byte) error { +func (j *License) UnmarshalJSON(b []byte) error { var v string if err := json.Unmarshal(b, &v); err != nil { return err } var ok bool - for _, expected := range enumValues_License_1 { + for _, expected := range enumValues_License { if reflect.DeepEqual(v, expected) { ok = true break } } if !ok { - return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_License_1, v) + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_License, v) } - *j = License_1(v) + *j = License(v) return nil } -var enumValues_License = []interface{}{ - "GPL-3.0", - "MIT", -} - -// UnmarshalJSON implements json.Unmarshaler. -func (j *License) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *License) UnmarshalYAML(value *yaml.Node) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := value.Decode(&v); err != nil { return err } var ok bool @@ -66,23 +70,6 @@ func (j *License) UnmarshalJSON(b []byte) error { return nil } -type SpecialCharacters struct { - // PlainLicenses corresponds to the JSON schema field "plainLicenses". - PlainLicenses *SpecialCharactersPlainLicenses `json:"plainLicenses,omitempty" yaml:"plainLicenses,omitempty" mapstructure:"plainLicenses,omitempty"` - - // PlainLicensesRef corresponds to the JSON schema field "plainLicensesRef". - PlainLicensesRef []License `json:"plainLicensesRef,omitempty" yaml:"plainLicensesRef,omitempty" mapstructure:"plainLicensesRef,omitempty"` - - // PlusLicenses corresponds to the JSON schema field "plusLicenses". - PlusLicenses *SpecialCharactersPlusLicenses `json:"plusLicenses,omitempty" yaml:"plusLicenses,omitempty" mapstructure:"plusLicenses,omitempty"` - - // PlusLicensesRef corresponds to the JSON schema field "plusLicensesRef". - PlusLicensesRef []License_1 `json:"plusLicensesRef,omitempty" yaml:"plusLicensesRef,omitempty" mapstructure:"plusLicensesRef,omitempty"` -} - -type SpecialCharactersPlainLicenses string - -const SpecialCharactersPlainLicensesGPL30 SpecialCharactersPlainLicenses = "GPL-3.0" const SpecialCharactersPlainLicensesMIT SpecialCharactersPlainLicenses = "MIT" var enumValues_SpecialCharactersPlainLicenses = []interface{}{ @@ -112,8 +99,25 @@ func (j *SpecialCharactersPlainLicenses) UnmarshalJSON(b []byte) error { type SpecialCharactersPlusLicenses string -const SpecialCharactersPlusLicensesGPL30 SpecialCharactersPlusLicenses = "GPL-3.0+" -const SpecialCharactersPlusLicensesMIT SpecialCharactersPlusLicenses = "MIT+" +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *SpecialCharactersPlainLicenses) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_SpecialCharactersPlainLicenses { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_SpecialCharactersPlainLicenses, v) + } + *j = SpecialCharactersPlainLicenses(v) + return nil +} var enumValues_SpecialCharactersPlusLicenses = []interface{}{ "GPL-3.0+", @@ -139,3 +143,31 @@ func (j *SpecialCharactersPlusLicenses) UnmarshalJSON(b []byte) error { *j = SpecialCharactersPlusLicenses(v) return nil } + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *SpecialCharactersPlusLicenses) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_SpecialCharactersPlusLicenses { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_SpecialCharactersPlusLicenses, v) + } + *j = SpecialCharactersPlusLicenses(v) + return nil +} + +const SpecialCharactersPlusLicensesGPL30 SpecialCharactersPlusLicenses = "GPL-3.0+" +const SpecialCharactersPlusLicensesMIT SpecialCharactersPlusLicenses = "MIT+" + +var enumValues_License = []interface{}{ + "GPL-3.0", + "MIT", +} diff --git a/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go b/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go index 403b41dd..23d4630d 100644 --- a/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go +++ b/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Bar struct { // RefToFoo corresponds to the JSON schema field "refToFoo". @@ -21,9 +22,9 @@ type Foo struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Foo) UnmarshalJSON(b []byte) error { +func (j *Foo) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["refToBar"]; raw != nil && !ok { @@ -31,7 +32,25 @@ func (j *Foo) UnmarshalJSON(b []byte) error { } type Plain Foo var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = Foo(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Foo) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["refToBar"]; !ok || v == nil { + return fmt.Errorf("field refToBar in Foo: required") + } + type Plain Foo + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = Foo(plain) diff --git a/tests/data/regressions/issue32/issue32.go b/tests/data/regressions/issue32/issue32.go index 7e4618ad..f6bffde7 100644 --- a/tests/data/regressions/issue32/issue32.go +++ b/tests/data/regressions/issue32/issue32.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type TestObject struct { // Config corresponds to the JSON schema field "config". @@ -19,9 +20,9 @@ type TestObject struct { type TestObjectConfig map[string]interface{} // UnmarshalJSON implements json.Unmarshaler. -func (j *TestObject) UnmarshalJSON(b []byte) error { +func (j *TestObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["name"]; raw != nil && !ok { @@ -32,7 +33,28 @@ func (j *TestObject) UnmarshalJSON(b []byte) error { } type Plain TestObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = TestObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *TestObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["name"]; !ok || v == nil { + return fmt.Errorf("field name in TestObject: required") + } + if v, ok := raw["owner"]; !ok || v == nil { + return fmt.Errorf("field owner in TestObject: required") + } + type Plain TestObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = TestObject(plain) diff --git a/tests/data/validation/enum/enum.go b/tests/data/validation/enum/enum.go index 2f6ae569..3377e20f 100644 --- a/tests/data/validation/enum/enum.go +++ b/tests/data/validation/enum/enum.go @@ -4,44 +4,9 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "reflect" -type Enum struct { - // MyBooleanTypedEnum corresponds to the JSON schema field "myBooleanTypedEnum". - MyBooleanTypedEnum *EnumMyBooleanTypedEnum `json:"myBooleanTypedEnum,omitempty" yaml:"myBooleanTypedEnum,omitempty" mapstructure:"myBooleanTypedEnum,omitempty"` - - // MyBooleanUntypedEnum corresponds to the JSON schema field - // "myBooleanUntypedEnum". - MyBooleanUntypedEnum *EnumMyBooleanUntypedEnum `json:"myBooleanUntypedEnum,omitempty" yaml:"myBooleanUntypedEnum,omitempty" mapstructure:"myBooleanUntypedEnum,omitempty"` - - // MyIntegerTypedEnum corresponds to the JSON schema field "myIntegerTypedEnum". - MyIntegerTypedEnum *EnumMyIntegerTypedEnum `json:"myIntegerTypedEnum,omitempty" yaml:"myIntegerTypedEnum,omitempty" mapstructure:"myIntegerTypedEnum,omitempty"` - - // MyMixedTypeEnum corresponds to the JSON schema field "myMixedTypeEnum". - MyMixedTypeEnum *EnumMyMixedTypeEnum `json:"myMixedTypeEnum,omitempty" yaml:"myMixedTypeEnum,omitempty" mapstructure:"myMixedTypeEnum,omitempty"` - - // MyMixedUntypedEnum corresponds to the JSON schema field "myMixedUntypedEnum". - MyMixedUntypedEnum *EnumMyMixedUntypedEnum `json:"myMixedUntypedEnum,omitempty" yaml:"myMixedUntypedEnum,omitempty" mapstructure:"myMixedUntypedEnum,omitempty"` - - // MyNullTypedEnum corresponds to the JSON schema field "myNullTypedEnum". - MyNullTypedEnum *EnumMyNullTypedEnum `json:"myNullTypedEnum,omitempty" yaml:"myNullTypedEnum,omitempty" mapstructure:"myNullTypedEnum,omitempty"` - - // MyNullUntypedEnum corresponds to the JSON schema field "myNullUntypedEnum". - MyNullUntypedEnum *EnumMyNullUntypedEnum `json:"myNullUntypedEnum,omitempty" yaml:"myNullUntypedEnum,omitempty" mapstructure:"myNullUntypedEnum,omitempty"` - - // MyNumberTypedEnum corresponds to the JSON schema field "myNumberTypedEnum". - MyNumberTypedEnum *EnumMyNumberTypedEnum `json:"myNumberTypedEnum,omitempty" yaml:"myNumberTypedEnum,omitempty" mapstructure:"myNumberTypedEnum,omitempty"` - - // MyNumberUntypedEnum corresponds to the JSON schema field "myNumberUntypedEnum". - MyNumberUntypedEnum *EnumMyNumberUntypedEnum `json:"myNumberUntypedEnum,omitempty" yaml:"myNumberUntypedEnum,omitempty" mapstructure:"myNumberUntypedEnum,omitempty"` - - // MyStringTypedEnum corresponds to the JSON schema field "myStringTypedEnum". - MyStringTypedEnum *EnumMyStringTypedEnum `json:"myStringTypedEnum,omitempty" yaml:"myStringTypedEnum,omitempty" mapstructure:"myStringTypedEnum,omitempty"` - - // MyStringUntypedEnum corresponds to the JSON schema field "myStringUntypedEnum". - MyStringUntypedEnum *EnumMyStringUntypedEnum `json:"myStringUntypedEnum,omitempty" yaml:"myStringUntypedEnum,omitempty" mapstructure:"myStringUntypedEnum,omitempty"` -} - type EnumMyBooleanTypedEnum bool var enumValues_EnumMyBooleanTypedEnum = []interface{}{ @@ -69,6 +34,26 @@ func (j *EnumMyBooleanTypedEnum) UnmarshalJSON(b []byte) error { return nil } +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyBooleanTypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v bool + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyBooleanTypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyBooleanTypedEnum, v) + } + *j = EnumMyBooleanTypedEnum(v) + return nil +} + type EnumMyBooleanUntypedEnum bool var enumValues_EnumMyBooleanUntypedEnum = []interface{}{ @@ -96,6 +81,26 @@ func (j *EnumMyBooleanUntypedEnum) UnmarshalJSON(b []byte) error { return nil } +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyBooleanUntypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v bool + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyBooleanUntypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyBooleanUntypedEnum, v) + } + *j = EnumMyBooleanUntypedEnum(v) + return nil +} + type EnumMyIntegerTypedEnum int var enumValues_EnumMyIntegerTypedEnum = []interface{}{ @@ -124,13 +129,28 @@ func (j *EnumMyIntegerTypedEnum) UnmarshalJSON(b []byte) error { return nil } -type EnumMyMixedTypeEnum struct { - Value interface{} +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyIntegerTypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v int + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyIntegerTypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyIntegerTypedEnum, v) + } + *j = EnumMyIntegerTypedEnum(v) + return nil } -// MarshalJSON implements json.Marshaler. -func (j *EnumMyMixedTypeEnum) MarshalJSON() ([]byte, error) { - return json.Marshal(j.Value) +type EnumMyMixedTypeEnum struct { + Value interface{} } var enumValues_EnumMyMixedTypeEnum = []interface{}{ @@ -138,6 +158,11 @@ var enumValues_EnumMyMixedTypeEnum = []interface{}{ "smurf", } +// MarshalJSON implements json.Marshaler. +func (j *EnumMyMixedTypeEnum) MarshalJSON() ([]byte, error) { + return json.Marshal(j.Value) +} + // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyMixedTypeEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -160,13 +185,35 @@ func (j *EnumMyMixedTypeEnum) UnmarshalJSON(b []byte) error { return nil } -type EnumMyMixedUntypedEnum struct { - Value interface{} +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyMixedTypeEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) } -// MarshalJSON implements json.Marshaler. -func (j *EnumMyMixedUntypedEnum) MarshalJSON() ([]byte, error) { - return json.Marshal(j.Value) +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyMixedTypeEnum) UnmarshalYAML(value *yaml.Node) error { + var v struct { + Value interface{} + } + if err := value.Decode(&v.Value); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyMixedTypeEnum { + if reflect.DeepEqual(v.Value, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyMixedTypeEnum, v.Value) + } + *j = EnumMyMixedTypeEnum(v) + return nil +} + +type EnumMyMixedUntypedEnum struct { + Value interface{} } var enumValues_EnumMyMixedUntypedEnum = []interface{}{ @@ -176,6 +223,11 @@ var enumValues_EnumMyMixedUntypedEnum = []interface{}{ nil, } +// MarshalJSON implements json.Marshaler. +func (j *EnumMyMixedUntypedEnum) MarshalJSON() ([]byte, error) { + return json.Marshal(j.Value) +} + // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyMixedUntypedEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -198,19 +250,46 @@ func (j *EnumMyMixedUntypedEnum) UnmarshalJSON(b []byte) error { return nil } +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyMixedUntypedEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyMixedUntypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v struct { + Value interface{} + } + if err := value.Decode(&v.Value); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyMixedUntypedEnum { + if reflect.DeepEqual(v.Value, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyMixedUntypedEnum, v.Value) + } + *j = EnumMyMixedUntypedEnum(v) + return nil +} + type EnumMyNullTypedEnum struct { Value interface{} } +var enumValues_EnumMyNullTypedEnum = []interface{}{ + nil, +} + // MarshalJSON implements json.Marshaler. func (j *EnumMyNullTypedEnum) MarshalJSON() ([]byte, error) { return json.Marshal(j.Value) } -var enumValues_EnumMyNullTypedEnum = []interface{}{ - nil, -} - // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyNullTypedEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -233,6 +312,37 @@ func (j *EnumMyNullTypedEnum) UnmarshalJSON(b []byte) error { return nil } +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyNullTypedEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyNullTypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v struct { + Value interface{} + } + if err := value.Decode(&v.Value); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyNullTypedEnum { + if reflect.DeepEqual(v.Value, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyNullTypedEnum, v.Value) + } + *j = EnumMyNullTypedEnum(v) + return nil +} + +var enumValues_EnumMyNullUntypedEnum = []interface{}{ + nil, +} + type EnumMyNullUntypedEnum struct { Value interface{} } @@ -242,10 +352,6 @@ func (j *EnumMyNullUntypedEnum) MarshalJSON() ([]byte, error) { return json.Marshal(j.Value) } -var enumValues_EnumMyNullUntypedEnum = []interface{}{ - nil, -} - // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyNullUntypedEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -268,6 +374,33 @@ func (j *EnumMyNullUntypedEnum) UnmarshalJSON(b []byte) error { return nil } +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyNullUntypedEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyNullUntypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v struct { + Value interface{} + } + if err := value.Decode(&v.Value); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyNullUntypedEnum { + if reflect.DeepEqual(v.Value, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyNullUntypedEnum, v.Value) + } + *j = EnumMyNullUntypedEnum(v) + return nil +} + type EnumMyNumberTypedEnum float64 var enumValues_EnumMyNumberTypedEnum = []interface{}{ @@ -296,6 +429,26 @@ func (j *EnumMyNumberTypedEnum) UnmarshalJSON(b []byte) error { return nil } +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyNumberTypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v float64 + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyNumberTypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyNumberTypedEnum, v) + } + *j = EnumMyNumberTypedEnum(v) + return nil +} + type EnumMyNumberUntypedEnum float64 var enumValues_EnumMyNumberUntypedEnum = []interface{}{ @@ -324,11 +477,27 @@ func (j *EnumMyNumberUntypedEnum) UnmarshalJSON(b []byte) error { return nil } -type EnumMyStringTypedEnum string +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyNumberUntypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v float64 + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyNumberUntypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyNumberUntypedEnum, v) + } + *j = EnumMyNumberUntypedEnum(v) + return nil +} -const EnumMyStringTypedEnumBlue EnumMyStringTypedEnum = "blue" -const EnumMyStringTypedEnumGreen EnumMyStringTypedEnum = "green" -const EnumMyStringTypedEnumRed EnumMyStringTypedEnum = "red" +type EnumMyStringTypedEnum string var enumValues_EnumMyStringTypedEnum = []interface{}{ "red", @@ -356,11 +525,31 @@ func (j *EnumMyStringTypedEnum) UnmarshalJSON(b []byte) error { return nil } -type EnumMyStringUntypedEnum string +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyStringTypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyStringTypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyStringTypedEnum, v) + } + *j = EnumMyStringTypedEnum(v) + return nil +} -const EnumMyStringUntypedEnumBlue EnumMyStringUntypedEnum = "blue" -const EnumMyStringUntypedEnumGreen EnumMyStringUntypedEnum = "green" -const EnumMyStringUntypedEnumRed EnumMyStringUntypedEnum = "red" +const EnumMyStringTypedEnumBlue EnumMyStringTypedEnum = "blue" +const EnumMyStringTypedEnumGreen EnumMyStringTypedEnum = "green" +const EnumMyStringTypedEnumRed EnumMyStringTypedEnum = "red" + +type EnumMyStringUntypedEnum string var enumValues_EnumMyStringUntypedEnum = []interface{}{ "red", @@ -387,3 +576,63 @@ func (j *EnumMyStringUntypedEnum) UnmarshalJSON(b []byte) error { *j = EnumMyStringUntypedEnum(v) return nil } + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyStringUntypedEnum) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_EnumMyStringUntypedEnum { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EnumMyStringUntypedEnum, v) + } + *j = EnumMyStringUntypedEnum(v) + return nil +} + +type Enum struct { + // MyBooleanTypedEnum corresponds to the JSON schema field "myBooleanTypedEnum". + MyBooleanTypedEnum *EnumMyBooleanTypedEnum `json:"myBooleanTypedEnum,omitempty" yaml:"myBooleanTypedEnum,omitempty" mapstructure:"myBooleanTypedEnum,omitempty"` + + // MyBooleanUntypedEnum corresponds to the JSON schema field + // "myBooleanUntypedEnum". + MyBooleanUntypedEnum *EnumMyBooleanUntypedEnum `json:"myBooleanUntypedEnum,omitempty" yaml:"myBooleanUntypedEnum,omitempty" mapstructure:"myBooleanUntypedEnum,omitempty"` + + // MyIntegerTypedEnum corresponds to the JSON schema field "myIntegerTypedEnum". + MyIntegerTypedEnum *EnumMyIntegerTypedEnum `json:"myIntegerTypedEnum,omitempty" yaml:"myIntegerTypedEnum,omitempty" mapstructure:"myIntegerTypedEnum,omitempty"` + + // MyMixedTypeEnum corresponds to the JSON schema field "myMixedTypeEnum". + MyMixedTypeEnum *EnumMyMixedTypeEnum `json:"myMixedTypeEnum,omitempty" yaml:"myMixedTypeEnum,omitempty" mapstructure:"myMixedTypeEnum,omitempty"` + + // MyMixedUntypedEnum corresponds to the JSON schema field "myMixedUntypedEnum". + MyMixedUntypedEnum *EnumMyMixedUntypedEnum `json:"myMixedUntypedEnum,omitempty" yaml:"myMixedUntypedEnum,omitempty" mapstructure:"myMixedUntypedEnum,omitempty"` + + // MyNullTypedEnum corresponds to the JSON schema field "myNullTypedEnum". + MyNullTypedEnum *EnumMyNullTypedEnum `json:"myNullTypedEnum,omitempty" yaml:"myNullTypedEnum,omitempty" mapstructure:"myNullTypedEnum,omitempty"` + + // MyNullUntypedEnum corresponds to the JSON schema field "myNullUntypedEnum". + MyNullUntypedEnum *EnumMyNullUntypedEnum `json:"myNullUntypedEnum,omitempty" yaml:"myNullUntypedEnum,omitempty" mapstructure:"myNullUntypedEnum,omitempty"` + + // MyNumberTypedEnum corresponds to the JSON schema field "myNumberTypedEnum". + MyNumberTypedEnum *EnumMyNumberTypedEnum `json:"myNumberTypedEnum,omitempty" yaml:"myNumberTypedEnum,omitempty" mapstructure:"myNumberTypedEnum,omitempty"` + + // MyNumberUntypedEnum corresponds to the JSON schema field "myNumberUntypedEnum". + MyNumberUntypedEnum *EnumMyNumberUntypedEnum `json:"myNumberUntypedEnum,omitempty" yaml:"myNumberUntypedEnum,omitempty" mapstructure:"myNumberUntypedEnum,omitempty"` + + // MyStringTypedEnum corresponds to the JSON schema field "myStringTypedEnum". + MyStringTypedEnum *EnumMyStringTypedEnum `json:"myStringTypedEnum,omitempty" yaml:"myStringTypedEnum,omitempty" mapstructure:"myStringTypedEnum,omitempty"` + + // MyStringUntypedEnum corresponds to the JSON schema field "myStringUntypedEnum". + MyStringUntypedEnum *EnumMyStringUntypedEnum `json:"myStringUntypedEnum,omitempty" yaml:"myStringUntypedEnum,omitempty" mapstructure:"myStringUntypedEnum,omitempty"` +} + +const EnumMyStringUntypedEnumBlue EnumMyStringUntypedEnum = "blue" +const EnumMyStringUntypedEnumGreen EnumMyStringUntypedEnum = "green" +const EnumMyStringUntypedEnumRed EnumMyStringUntypedEnum = "red" diff --git a/tests/data/validation/maxItems/maxItems.go b/tests/data/validation/maxItems/maxItems.go index 562642dc..fbe7a99e 100644 --- a/tests/data/validation/maxItems/maxItems.go +++ b/tests/data/validation/maxItems/maxItems.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type MaxItems struct { // MyNestedArray corresponds to the JSON schema field "myNestedArray". @@ -14,14 +15,40 @@ type MaxItems struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *MaxItems) UnmarshalJSON(b []byte) error { +func (j *MaxItems) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain MaxItems var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if len(plain.MyNestedArray) > 5 { + return fmt.Errorf("field %s length: must be <= %d", "myNestedArray", 5) + } + for i1 := range plain.MyNestedArray { + if len(plain.MyNestedArray[i1]) > 5 { + return fmt.Errorf("field %s length: must be <= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) + } + } + if len(plain.MyStringArray) > 5 { + return fmt.Errorf("field %s length: must be <= %d", "myStringArray", 5) + } + *j = MaxItems(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MaxItems) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain MaxItems + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if len(plain.MyNestedArray) > 5 { diff --git a/tests/data/validation/maxLength/maxLength.go b/tests/data/validation/maxLength/maxLength.go index c4ea0324..ca734ecd 100644 --- a/tests/data/validation/maxLength/maxLength.go +++ b/tests/data/validation/maxLength/maxLength.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type MaxLength struct { // MyNullableString corresponds to the JSON schema field "myNullableString". @@ -14,9 +15,9 @@ type MaxLength struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *MaxLength) UnmarshalJSON(b []byte) error { +func (j *MaxLength) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myString"]; raw != nil && !ok { @@ -24,7 +25,31 @@ func (j *MaxLength) UnmarshalJSON(b []byte) error { } type Plain MaxLength var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyNullableString != nil && len(*plain.MyNullableString) > 10 { + return fmt.Errorf("field %s length: must be <= %d", "myNullableString", 10) + } + if len(plain.MyString) > 5 { + return fmt.Errorf("field %s length: must be <= %d", "myString", 5) + } + *j = MaxLength(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MaxLength) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myString"]; !ok || v == nil { + return fmt.Errorf("field myString in MaxLength: required") + } + type Plain MaxLength + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyNullableString != nil && len(*plain.MyNullableString) > 10 { diff --git a/tests/data/validation/minItems/minItems.go b/tests/data/validation/minItems/minItems.go index 17df697c..050b2594 100644 --- a/tests/data/validation/minItems/minItems.go +++ b/tests/data/validation/minItems/minItems.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type MinItems struct { // MyNestedArray corresponds to the JSON schema field "myNestedArray". @@ -14,14 +15,40 @@ type MinItems struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *MinItems) UnmarshalJSON(b []byte) error { +func (j *MinItems) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain MinItems var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyNestedArray != nil && len(plain.MyNestedArray) < 5 { + return fmt.Errorf("field %s length: must be >= %d", "myNestedArray", 5) + } + for i1 := range plain.MyNestedArray { + if plain.MyNestedArray[i1] != nil && len(plain.MyNestedArray[i1]) < 5 { + return fmt.Errorf("field %s length: must be >= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) + } + } + if plain.MyStringArray != nil && len(plain.MyStringArray) < 5 { + return fmt.Errorf("field %s length: must be >= %d", "myStringArray", 5) + } + *j = MinItems(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MinItems) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain MinItems + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyNestedArray != nil && len(plain.MyNestedArray) < 5 { diff --git a/tests/data/validation/minLength/minLength.go b/tests/data/validation/minLength/minLength.go index 3f3f7395..1e18295f 100644 --- a/tests/data/validation/minLength/minLength.go +++ b/tests/data/validation/minLength/minLength.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type MinLength struct { // MyNullableString corresponds to the JSON schema field "myNullableString". @@ -14,9 +15,9 @@ type MinLength struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *MinLength) UnmarshalJSON(b []byte) error { +func (j *MinLength) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myString"]; raw != nil && !ok { @@ -24,7 +25,31 @@ func (j *MinLength) UnmarshalJSON(b []byte) error { } type Plain MinLength var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyNullableString != nil && len(*plain.MyNullableString) < 10 { + return fmt.Errorf("field %s length: must be >= %d", "myNullableString", 10) + } + if len(plain.MyString) < 5 { + return fmt.Errorf("field %s length: must be >= %d", "myString", 5) + } + *j = MinLength(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MinLength) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myString"]; !ok || v == nil { + return fmt.Errorf("field myString in MinLength: required") + } + type Plain MinLength + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyNullableString != nil && len(*plain.MyNullableString) < 10 { diff --git a/tests/data/validation/minMaxItems/minMaxItems.go b/tests/data/validation/minMaxItems/minMaxItems.go index 5f60d3eb..1d338c8f 100644 --- a/tests/data/validation/minMaxItems/minMaxItems.go +++ b/tests/data/validation/minMaxItems/minMaxItems.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type MinMaxItems struct { // MyNestedArray corresponds to the JSON schema field "myNestedArray". @@ -14,14 +15,49 @@ type MinMaxItems struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *MinMaxItems) UnmarshalJSON(b []byte) error { +func (j *MinMaxItems) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain MinMaxItems var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyNestedArray != nil && len(plain.MyNestedArray) < 1 { + return fmt.Errorf("field %s length: must be >= %d", "myNestedArray", 1) + } + if len(plain.MyNestedArray) > 5 { + return fmt.Errorf("field %s length: must be <= %d", "myNestedArray", 5) + } + for i1 := range plain.MyNestedArray { + if plain.MyNestedArray[i1] != nil && len(plain.MyNestedArray[i1]) < 1 { + return fmt.Errorf("field %s length: must be >= %d", fmt.Sprintf("myNestedArray[%d]", i1), 1) + } + if len(plain.MyNestedArray[i1]) > 5 { + return fmt.Errorf("field %s length: must be <= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) + } + } + if plain.MyStringArray != nil && len(plain.MyStringArray) < 1 { + return fmt.Errorf("field %s length: must be >= %d", "myStringArray", 1) + } + if len(plain.MyStringArray) > 3 { + return fmt.Errorf("field %s length: must be <= %d", "myStringArray", 3) + } + *j = MinMaxItems(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MinMaxItems) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain MinMaxItems + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyNestedArray != nil && len(plain.MyNestedArray) < 1 { diff --git a/tests/data/validation/requiredFields/requiredFields.go b/tests/data/validation/requiredFields/requiredFields.go index 534ac4c2..fef61227 100644 --- a/tests/data/validation/requiredFields/requiredFields.go +++ b/tests/data/validation/requiredFields/requiredFields.go @@ -4,6 +4,91 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" + +type RequiredFieldsMyObject struct { + // MyNestedObjectString corresponds to the JSON schema field + // "myNestedObjectString". + MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *RequiredFieldsMyObject) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if v, ok := raw["myNestedObjectString"]; !ok || v == nil { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") + } + type Plain RequiredFieldsMyObject + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = RequiredFieldsMyObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *RequiredFieldsMyObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myNestedObjectString"]; !ok || v == nil { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") + } + type Plain RequiredFieldsMyObject + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = RequiredFieldsMyObject(plain) + return nil +} + +type RequiredFieldsMyObjectArrayElem struct { + // MyNestedObjectString corresponds to the JSON schema field + // "myNestedObjectString". + MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *RequiredFieldsMyObjectArrayElem) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if v, ok := raw["myNestedObjectString"]; !ok || v == nil { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") + } + type Plain RequiredFieldsMyObjectArrayElem + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = RequiredFieldsMyObjectArrayElem(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *RequiredFieldsMyObjectArrayElem) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if v, ok := raw["myNestedObjectString"]; !ok || v == nil { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") + } + type Plain RequiredFieldsMyObjectArrayElem + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = RequiredFieldsMyObjectArrayElem(plain) + return nil +} type RequiredFields struct { // MyBoolean corresponds to the JSON schema field "myBoolean". @@ -43,93 +128,98 @@ type RequiredFields struct { MyStringArray []string `json:"myStringArray" yaml:"myStringArray" mapstructure:"myStringArray"` } -type RequiredFieldsMyObject struct { - // MyNestedObjectString corresponds to the JSON schema field - // "myNestedObjectString". - MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` -} - -type RequiredFieldsMyObjectArrayElem struct { - // MyNestedObjectString corresponds to the JSON schema field - // "myNestedObjectString". - MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` -} - // UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredFieldsMyObjectArrayElem) UnmarshalJSON(b []byte) error { +func (j *RequiredFields) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } - if _, ok := raw["myNestedObjectString"]; raw != nil && !ok { - return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") + if _, ok := raw["myBoolean"]; raw != nil && !ok { + return fmt.Errorf("field myBoolean in RequiredFields: required") } - type Plain RequiredFieldsMyObjectArrayElem - var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { - return err + if _, ok := raw["myBooleanArray"]; raw != nil && !ok { + return fmt.Errorf("field myBooleanArray in RequiredFields: required") } - *j = RequiredFieldsMyObjectArrayElem(plain) - return nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredFieldsMyObject) UnmarshalJSON(b []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { - return err + if _, ok := raw["myNull"]; raw != nil && !ok { + return fmt.Errorf("field myNull in RequiredFields: required") } - if _, ok := raw["myNestedObjectString"]; raw != nil && !ok { - return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") + if _, ok := raw["myNullArray"]; raw != nil && !ok { + return fmt.Errorf("field myNullArray in RequiredFields: required") } - type Plain RequiredFieldsMyObject + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in RequiredFields: required") + } + if _, ok := raw["myNumberArray"]; raw != nil && !ok { + return fmt.Errorf("field myNumberArray in RequiredFields: required") + } + if _, ok := raw["myObject"]; raw != nil && !ok { + return fmt.Errorf("field myObject in RequiredFields: required") + } + if _, ok := raw["myObjectArray"]; raw != nil && !ok { + return fmt.Errorf("field myObjectArray in RequiredFields: required") + } + if _, ok := raw["myString"]; raw != nil && !ok { + return fmt.Errorf("field myString in RequiredFields: required") + } + if _, ok := raw["myStringArray"]; raw != nil && !ok { + return fmt.Errorf("field myStringArray in RequiredFields: required") + } + type Plain RequiredFields var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } - *j = RequiredFieldsMyObject(plain) + if plain.MyNull != nil { + return fmt.Errorf("field %s: must be null", "myNull") + } + for i0 := range plain.MyNullArray { + if plain.MyNullArray[i0] != nil { + return fmt.Errorf("field %s: must be null", fmt.Sprintf("myNullArray[%d]", i0)) + } + } + *j = RequiredFields(plain) return nil } -// UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredFields) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *RequiredFields) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := value.Decode(&raw); err != nil { return err } - if _, ok := raw["myBoolean"]; raw != nil && !ok { + if v, ok := raw["myBoolean"]; !ok || v == nil { return fmt.Errorf("field myBoolean in RequiredFields: required") } - if _, ok := raw["myBooleanArray"]; raw != nil && !ok { + if v, ok := raw["myBooleanArray"]; !ok || v == nil { return fmt.Errorf("field myBooleanArray in RequiredFields: required") } - if _, ok := raw["myNull"]; raw != nil && !ok { + if v, ok := raw["myNull"]; !ok || v == nil { return fmt.Errorf("field myNull in RequiredFields: required") } - if _, ok := raw["myNullArray"]; raw != nil && !ok { + if v, ok := raw["myNullArray"]; !ok || v == nil { return fmt.Errorf("field myNullArray in RequiredFields: required") } - if _, ok := raw["myNumber"]; raw != nil && !ok { + if v, ok := raw["myNumber"]; !ok || v == nil { return fmt.Errorf("field myNumber in RequiredFields: required") } - if _, ok := raw["myNumberArray"]; raw != nil && !ok { + if v, ok := raw["myNumberArray"]; !ok || v == nil { return fmt.Errorf("field myNumberArray in RequiredFields: required") } - if _, ok := raw["myObject"]; raw != nil && !ok { + if v, ok := raw["myObject"]; !ok || v == nil { return fmt.Errorf("field myObject in RequiredFields: required") } - if _, ok := raw["myObjectArray"]; raw != nil && !ok { + if v, ok := raw["myObjectArray"]; !ok || v == nil { return fmt.Errorf("field myObjectArray in RequiredFields: required") } - if _, ok := raw["myString"]; raw != nil && !ok { + if v, ok := raw["myString"]; !ok || v == nil { return fmt.Errorf("field myString in RequiredFields: required") } - if _, ok := raw["myStringArray"]; raw != nil && !ok { + if v, ok := raw["myStringArray"]; !ok || v == nil { return fmt.Errorf("field myStringArray in RequiredFields: required") } type Plain RequiredFields var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } if plain.MyNull != nil { diff --git a/tests/data/validation/typed_default/typed_default.go b/tests/data/validation/typed_default/typed_default.go index b30c1bd0..dfd38b8d 100644 --- a/tests/data/validation/typed_default/typed_default.go +++ b/tests/data/validation/typed_default/typed_default.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type TypedDefault struct { // TopLevelDomains corresponds to the JSON schema field "topLevelDomains". @@ -10,14 +11,37 @@ type TypedDefault struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *TypedDefault) UnmarshalJSON(b []byte) error { +func (j *TypedDefault) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain TypedDefault var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["topLevelDomains"]; !ok || v == nil { + plain.TopLevelDomains = []string{ + ".com", + ".org", + ".info", + ".gov", + } + } + *j = TypedDefault(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *TypedDefault) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain TypedDefault + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw["topLevelDomains"]; !ok || v == nil { diff --git a/tests/data/validation/typed_default_empty/typed_default_empty.go b/tests/data/validation/typed_default_empty/typed_default_empty.go index 322d2695..9b584f52 100644 --- a/tests/data/validation/typed_default_empty/typed_default_empty.go +++ b/tests/data/validation/typed_default_empty/typed_default_empty.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type TypedDefaultEmpty struct { // TopLevelDomains corresponds to the JSON schema field "topLevelDomains". @@ -10,14 +11,32 @@ type TypedDefaultEmpty struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *TypedDefaultEmpty) UnmarshalJSON(b []byte) error { +func (j *TypedDefaultEmpty) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain TypedDefaultEmpty var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["topLevelDomains"]; !ok || v == nil { + plain.TopLevelDomains = []string{} + } + *j = TypedDefaultEmpty(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *TypedDefaultEmpty) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain TypedDefaultEmpty + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw["topLevelDomains"]; !ok || v == nil { diff --git a/tests/data/validation/typed_default_enums/typed_default_enums.go b/tests/data/validation/typed_default_enums/typed_default_enums.go index e72e48b3..4d4f01d9 100644 --- a/tests/data/validation/typed_default_enums/typed_default_enums.go +++ b/tests/data/validation/typed_default_enums/typed_default_enums.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "reflect" type TypedDefaultEnums struct { @@ -41,15 +42,53 @@ func (j *TypedDefaultEnumsSome) UnmarshalJSON(b []byte) error { return nil } +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *TypedDefaultEnumsSome) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_TypedDefaultEnumsSome { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_TypedDefaultEnumsSome, v) + } + *j = TypedDefaultEnumsSome(v) + return nil +} + // UnmarshalJSON implements json.Unmarshaler. -func (j *TypedDefaultEnums) UnmarshalJSON(b []byte) error { +func (j *TypedDefaultEnums) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain TypedDefaultEnums + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["some"]; !ok || v == nil { + plain.Some = "random" + } + *j = TypedDefaultEnums(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *TypedDefaultEnums) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := value.Decode(&raw); err != nil { return err } type Plain TypedDefaultEnums var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw["some"]; !ok || v == nil { diff --git a/tests/generation_test.go b/tests/generation_test.go index ac26a335..588f47c4 100644 --- a/tests/generation_test.go +++ b/tests/generation_test.go @@ -18,7 +18,7 @@ var ( basicConfig = generator.Config{ SchemaMappings: []generator.SchemaMapping{}, - ExtraImports: false, + ExtraImports: true, DefaultPackageName: "github.com/example/test", DefaultOutputName: "-", ResolveExtensions: []string{".json", ".yaml"}, diff --git a/tests/go.mod b/tests/go.mod index 229e2580..3f3f19d4 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -14,8 +14,10 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/goccy/go-yaml v1.11.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index ba32eef3..02c79a4d 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -1,3 +1,5 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b h1:XxMZvQZtTXpWMNWK82vdjCLCe7uGMFXdTsJH0v3Hkvw= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= From 93e8f1d2450e16638ed4c45f8e554d1d0f7f61a0 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 20 Apr 2024 17:05:24 +0200 Subject: [PATCH 02/16] chore: update deps --- go.mod | 2 +- go.sum | 4 ++-- tests/go.mod | 6 +++--- tests/go.sum | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 98d02e99..9a3851c3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( dario.cat/mergo v1.0.0 github.com/goccy/go-yaml v1.11.3 - github.com/google/go-cmp v0.5.9 + github.com/google/go-cmp v0.6.0 github.com/mitchellh/go-wordwrap v1.0.1 github.com/pkg/errors v0.9.1 github.com/sanity-io/litter v1.5.5 diff --git a/go.sum b/go.sum index 38164695..8450e650 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7a github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= diff --git a/tests/go.mod b/tests/go.mod index 3f3f19d4..d163e582 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -8,8 +8,8 @@ replace ( ) require ( - github.com/atombender/go-jsonschema v0.15.0 - github.com/atombender/go-jsonschema/tests/helpers/other v0.0.0-20240416182955-738cf5ab9ab4 + github.com/atombender/go-jsonschema v0.16.0 + github.com/atombender/go-jsonschema/tests/helpers/other v0.0.0-20240420141435-0b49bf810988 gopkg.in/yaml.v3 v3.0.1 ) @@ -17,7 +17,7 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/goccy/go-yaml v1.11.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index 02c79a4d..26d01faf 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -12,8 +12,8 @@ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7a github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= From 24301f2687789314d0f60451f121f840f1b59446 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 20 Apr 2024 17:10:14 +0200 Subject: [PATCH 03/16] chore: fix linting issues --- pkg/generator/validator.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/generator/validator.go b/pkg/generator/validator.go index 10b8ddc9..148ea211 100644 --- a/pkg/generator/validator.go +++ b/pkg/generator/validator.go @@ -289,13 +289,13 @@ type anyOfValidator struct { } func (v *anyOfValidator) generate(out *codegen.Emitter, format string) { - for i := 0; i < v.elemCount; i++ { + for i := range v.elemCount { out.Printlnf(`var %s_%d %s_%d`, lowerFirst(v.fieldName), i, upperFirst(v.fieldName), i) } out.Printlnf(`var errs []error`) - for i := 0; i < v.elemCount; i++ { + for i := range v.elemCount { out.Printlnf( `if err := %s_%d.Unmarshal%s(value); err != nil {`, lowerFirst(v.fieldName), From 9390f1fa43135862b6089560f10761eaafc707eb Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 20 Apr 2024 17:24:41 +0200 Subject: [PATCH 04/16] fix: adapt additionalProperties tests after rebase --- .../arrayAdditionalProperties.go | 25 ++++++++++++++++--- .../boolAdditionalProperties.go | 25 ++++++++++++++++--- .../intAdditionalProperties.go | 25 ++++++++++++++++--- .../numberAdditionalProperties.go | 25 ++++++++++++++++--- .../objectAdditionalProperties.go | 25 ++++++++++++++++--- .../stringAdditionalProperties.go | 25 ++++++++++++++++--- 6 files changed, 132 insertions(+), 18 deletions(-) diff --git a/tests/data/core/additionalProperties/arrayAdditionalProperties.go b/tests/data/core/additionalProperties/arrayAdditionalProperties.go index e11133c4..1aa43404 100644 --- a/tests/data/core/additionalProperties/arrayAdditionalProperties.go +++ b/tests/data/core/additionalProperties/arrayAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type ArrayAdditionalProperties struct { // Name corresponds to the JSON schema field "name". @@ -12,14 +13,32 @@ type ArrayAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ArrayAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *ArrayAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain ArrayAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string][]interface{}{} + } + *j = ArrayAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ArrayAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain ArrayAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/core/additionalProperties/boolAdditionalProperties.go b/tests/data/core/additionalProperties/boolAdditionalProperties.go index 3a675118..34c95bfd 100644 --- a/tests/data/core/additionalProperties/boolAdditionalProperties.go +++ b/tests/data/core/additionalProperties/boolAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type BoolAdditionalProperties struct { // Name corresponds to the JSON schema field "name". @@ -12,14 +13,32 @@ type BoolAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *BoolAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *BoolAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain BoolAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string]bool{} + } + *j = BoolAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *BoolAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain BoolAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/core/additionalProperties/intAdditionalProperties.go b/tests/data/core/additionalProperties/intAdditionalProperties.go index cbd2b6c6..d4119617 100644 --- a/tests/data/core/additionalProperties/intAdditionalProperties.go +++ b/tests/data/core/additionalProperties/intAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type IntAdditionalProperties struct { // Name corresponds to the JSON schema field "name". @@ -12,14 +13,32 @@ type IntAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *IntAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *IntAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain IntAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string]int{} + } + *j = IntAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *IntAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain IntAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/core/additionalProperties/numberAdditionalProperties.go b/tests/data/core/additionalProperties/numberAdditionalProperties.go index 018cebbe..b3ff0560 100644 --- a/tests/data/core/additionalProperties/numberAdditionalProperties.go +++ b/tests/data/core/additionalProperties/numberAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type NumberAdditionalProperties struct { // Name corresponds to the JSON schema field "name". @@ -12,14 +13,32 @@ type NumberAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *NumberAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *NumberAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain NumberAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string]float64{} + } + *j = NumberAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *NumberAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain NumberAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/core/additionalProperties/objectAdditionalProperties.go b/tests/data/core/additionalProperties/objectAdditionalProperties.go index b300de35..23a34b77 100644 --- a/tests/data/core/additionalProperties/objectAdditionalProperties.go +++ b/tests/data/core/additionalProperties/objectAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type ObjectAdditionalProperties struct { // Name corresponds to the JSON schema field "name". @@ -12,14 +13,32 @@ type ObjectAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ObjectAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *ObjectAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain ObjectAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string]interface{}{} + } + *j = ObjectAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain ObjectAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/core/additionalProperties/stringAdditionalProperties.go b/tests/data/core/additionalProperties/stringAdditionalProperties.go index f00064f2..f6d4f6b0 100644 --- a/tests/data/core/additionalProperties/stringAdditionalProperties.go +++ b/tests/data/core/additionalProperties/stringAdditionalProperties.go @@ -3,6 +3,7 @@ package test import "encoding/json" +import yaml "gopkg.in/yaml.v3" type StringAdditionalProperties struct { // Name corresponds to the JSON schema field "name". @@ -12,14 +13,32 @@ type StringAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *StringAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *StringAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain StringAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string]string{} + } + *j = StringAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *StringAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain StringAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { From 848fd10c7d614a358b13a58b444861e95ac78efe Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 20 Apr 2024 17:24:52 +0200 Subject: [PATCH 05/16] fix: adapt date tests after rebase --- tests/data/core/date/date.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/core/date/date.go b/tests/data/core/date/date.go index 46f84ee3..87832d1b 100644 --- a/tests/data/core/date/date.go +++ b/tests/data/core/date/date.go @@ -41,7 +41,7 @@ func (j *DateMyObject) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myDate"]; !ok || v == nil { + if _, ok := raw["myDate"]; raw != nil && !ok { return fmt.Errorf("field myDate in DateMyObject: required") } type Plain DateMyObject From 6759adda4bd2c7976f0ff72b934926a16a33b46d Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 20 Apr 2024 17:58:55 +0200 Subject: [PATCH 06/16] fix: adapt tests with required fields after rebase --- tests/data/core/dateTime/dateTime.go | 2 +- tests/data/core/ip/ip.go | 2 +- tests/data/core/object/object.go | 2 +- tests/data/core/time/time.go | 2 +- tests/data/crossPackageNoOutput/other/other.go | 8 ++++++++ .../cyclicAndRequired1/cyclicAndRequired1.go | 2 +- tests/data/regressions/issue32/issue32.go | 4 ++-- 7 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 tests/data/crossPackageNoOutput/other/other.go diff --git a/tests/data/core/dateTime/dateTime.go b/tests/data/core/dateTime/dateTime.go index 33b91867..08e8da54 100644 --- a/tests/data/core/dateTime/dateTime.go +++ b/tests/data/core/dateTime/dateTime.go @@ -41,7 +41,7 @@ func (j *DateTimeMyObject) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myDateTime"]; !ok || v == nil { + if _, ok := raw["myDateTime"]; raw != nil && !ok { return fmt.Errorf("field myDateTime in DateTimeMyObject: required") } type Plain DateTimeMyObject diff --git a/tests/data/core/ip/ip.go b/tests/data/core/ip/ip.go index cda65d48..aa1868b7 100644 --- a/tests/data/core/ip/ip.go +++ b/tests/data/core/ip/ip.go @@ -41,7 +41,7 @@ func (j *IpMyObject) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myIp"]; !ok || v == nil { + if _, ok := raw["myIp"]; raw != nil && !ok { return fmt.Errorf("field myIp in IpMyObject: required") } type Plain IpMyObject diff --git a/tests/data/core/object/object.go b/tests/data/core/object/object.go index fd6fd023..a286f520 100644 --- a/tests/data/core/object/object.go +++ b/tests/data/core/object/object.go @@ -40,7 +40,7 @@ func (j *ObjectMyObject) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myString"]; !ok || v == nil { + if _, ok := raw["myString"]; raw != nil && !ok { return fmt.Errorf("field myString in ObjectMyObject: required") } type Plain ObjectMyObject diff --git a/tests/data/core/time/time.go b/tests/data/core/time/time.go index c083afe8..5997c297 100644 --- a/tests/data/core/time/time.go +++ b/tests/data/core/time/time.go @@ -41,7 +41,7 @@ func (j *TimeMyObject) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myTime"]; !ok || v == nil { + if _, ok := raw["myTime"]; raw != nil && !ok { return fmt.Errorf("field myTime in TimeMyObject: required") } type Plain TimeMyObject diff --git a/tests/data/crossPackageNoOutput/other/other.go b/tests/data/crossPackageNoOutput/other/other.go new file mode 100644 index 00000000..46f7e8ad --- /dev/null +++ b/tests/data/crossPackageNoOutput/other/other.go @@ -0,0 +1,8 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package test + +type Thing struct { + // S corresponds to the JSON schema field "s". + S *string `json:"s,omitempty" yaml:"s,omitempty" mapstructure:"s,omitempty"` +} diff --git a/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go b/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go index 23d4630d..d3dc6162 100644 --- a/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go +++ b/tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go @@ -45,7 +45,7 @@ func (j *Foo) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["refToBar"]; !ok || v == nil { + if _, ok := raw["refToBar"]; raw != nil && !ok { return fmt.Errorf("field refToBar in Foo: required") } type Plain Foo diff --git a/tests/data/regressions/issue32/issue32.go b/tests/data/regressions/issue32/issue32.go index f6bffde7..6f178703 100644 --- a/tests/data/regressions/issue32/issue32.go +++ b/tests/data/regressions/issue32/issue32.go @@ -46,10 +46,10 @@ func (j *TestObject) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["name"]; !ok || v == nil { + if _, ok := raw["name"]; raw != nil && !ok { return fmt.Errorf("field name in TestObject: required") } - if v, ok := raw["owner"]; !ok || v == nil { + if _, ok := raw["owner"]; raw != nil && !ok { return fmt.Errorf("field owner in TestObject: required") } type Plain TestObject From 49e9803b6bd10ff124651d1f2db72acc798b951c Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sun, 21 Apr 2024 01:20:47 +0200 Subject: [PATCH 07/16] fix: adapt remaining failing tests after rebase --- tests/data/core/allOf/allOf.go | 18 +- tests/data/core/allOf/issue6.go | 126 +++++++++ tests/data/core/allOf/issue6.json | 130 +++++++++ tests/data/core/anyOf/anyOf.go | 92 +++--- .../objectPropertiesDefault.go | 261 +++++++++--------- .../specialCharacters/specialCharacters.go | 103 +++++-- tests/data/validation/enum/enum.go | 188 ++++++------- tests/data/validation/maxLength/maxLength.go | 2 +- tests/data/validation/minLength/minLength.go | 2 +- .../requiredFields/requiredFields.go | 148 +++++----- .../requiredFields/requiredNullable.go | 55 +++- tests/generation_test.go | 12 +- 12 files changed, 742 insertions(+), 395 deletions(-) create mode 100644 tests/data/core/allOf/issue6.go create mode 100644 tests/data/core/allOf/issue6.json diff --git a/tests/data/core/allOf/allOf.go b/tests/data/core/allOf/allOf.go index fcd447e0..5b31ea6f 100644 --- a/tests/data/core/allOf/allOf.go +++ b/tests/data/core/allOf/allOf.go @@ -6,6 +6,11 @@ import "encoding/json" import "fmt" import yaml "gopkg.in/yaml.v3" +type AllOf struct { + // Configurations corresponds to the JSON schema field "configurations". + Configurations []AllOfConfigurationsElem `json:"configurations,omitempty" yaml:"configurations,omitempty" mapstructure:"configurations,omitempty"` +} + type AllOfConfigurationsElem struct { // Bar corresponds to the JSON schema field "bar". Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` @@ -20,10 +25,10 @@ func (j *AllOfConfigurationsElem) UnmarshalJSON(value []byte) error { if err := json.Unmarshal(value, &raw); err != nil { return err } - if v, ok := raw["bar"]; !ok || v == nil { + if _, ok := raw["bar"]; raw != nil && !ok { return fmt.Errorf("field bar in AllOfConfigurationsElem: required") } - if v, ok := raw["foo"]; !ok || v == nil { + if _, ok := raw["foo"]; raw != nil && !ok { return fmt.Errorf("field foo in AllOfConfigurationsElem: required") } type Plain AllOfConfigurationsElem @@ -41,10 +46,10 @@ func (j *AllOfConfigurationsElem) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["bar"]; !ok || v == nil { + if _, ok := raw["bar"]; raw != nil && !ok { return fmt.Errorf("field bar in AllOfConfigurationsElem: required") } - if v, ok := raw["foo"]; !ok || v == nil { + if _, ok := raw["foo"]; raw != nil && !ok { return fmt.Errorf("field foo in AllOfConfigurationsElem: required") } type Plain AllOfConfigurationsElem @@ -55,8 +60,3 @@ func (j *AllOfConfigurationsElem) UnmarshalYAML(value *yaml.Node) error { *j = AllOfConfigurationsElem(plain) return nil } - -type AllOf struct { - // Configurations corresponds to the JSON schema field "configurations". - Configurations []AllOfConfigurationsElem `json:"configurations,omitempty" yaml:"configurations,omitempty" mapstructure:"configurations,omitempty"` -} diff --git a/tests/data/core/allOf/issue6.go b/tests/data/core/allOf/issue6.go new file mode 100644 index 00000000..90005a11 --- /dev/null +++ b/tests/data/core/allOf/issue6.go @@ -0,0 +1,126 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package test + +import "encoding/json" +import "fmt" +import yaml "gopkg.in/yaml.v3" +import "reflect" + +// Base definition for all elements in a resource. +type Element interface{} + +// see http://hl7.org/fhir/json.html#schema for information about the FHIR Json +// Schemas +type Issue6 struct { + // A human's name with the ability to identify parts and usage. + Name *Issue6Name `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` +} + +// A human's name with the ability to identify parts and usage. +type Issue6Name struct { + // Extensions for family + Family Element `json:"_family,omitempty" yaml:"_family,omitempty" mapstructure:"_family,omitempty"` + + // Extensions for given + Given []Element `json:"_given,omitempty" yaml:"_given,omitempty" mapstructure:"_given,omitempty"` + + // Extensions for prefix + Prefix []Element `json:"_prefix,omitempty" yaml:"_prefix,omitempty" mapstructure:"_prefix,omitempty"` + + // Extensions for suffix + Suffix []Element `json:"_suffix,omitempty" yaml:"_suffix,omitempty" mapstructure:"_suffix,omitempty"` + + // Extensions for text + Text Element `json:"_text,omitempty" yaml:"_text,omitempty" mapstructure:"_text,omitempty"` + + // Extensions for use + Use Element `json:"_use,omitempty" yaml:"_use,omitempty" mapstructure:"_use,omitempty"` + + // The part of a name that links to the genealogy. In some cultures (e.g. Eritrea) + // the family name of a son is the first name of his father. + Family_2 *string `json:"family,omitempty" yaml:"family,omitempty" mapstructure:"family,omitempty"` + + // Given name. + Given_2 []string `json:"given,omitempty" yaml:"given,omitempty" mapstructure:"given,omitempty"` + + // Indicates the period of time when this name was valid for the named person. + Period Period `json:"period,omitempty" yaml:"period,omitempty" mapstructure:"period,omitempty"` + + // Part of the name that is acquired as a title due to academic, legal, employment + // or nobility status, etc. and that appears at the start of the name. + Prefix_2 []string `json:"prefix,omitempty" yaml:"prefix,omitempty" mapstructure:"prefix,omitempty"` + + // Part of the name that is acquired as a title due to academic, legal, employment + // or nobility status, etc. and that appears at the end of the name. + Suffix_2 []string `json:"suffix,omitempty" yaml:"suffix,omitempty" mapstructure:"suffix,omitempty"` + + // A full text representation of the name. + Text_2 *string `json:"text,omitempty" yaml:"text,omitempty" mapstructure:"text,omitempty"` + + // Identifies the purpose for this name. + Use_2 *Issue6NameUse_2 `json:"use,omitempty" yaml:"use,omitempty" mapstructure:"use,omitempty"` +} + +type Issue6NameUse_2 string + +const Issue6NameUse_2_Anonymous Issue6NameUse_2 = "anonymous" +const Issue6NameUse_2_Maiden Issue6NameUse_2 = "maiden" +const Issue6NameUse_2_Nickname Issue6NameUse_2 = "nickname" +const Issue6NameUse_2_Official Issue6NameUse_2 = "official" +const Issue6NameUse_2_Old Issue6NameUse_2 = "old" +const Issue6NameUse_2_Temp Issue6NameUse_2 = "temp" +const Issue6NameUse_2_Usual Issue6NameUse_2 = "usual" + +var enumValues_Issue6NameUse_2 = []interface{}{ + "usual", + "official", + "temp", + "nickname", + "anonymous", + "old", + "maiden", +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Issue6NameUse_2) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_Issue6NameUse_2 { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Issue6NameUse_2, v) + } + *j = Issue6NameUse_2(v) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *Issue6NameUse_2) UnmarshalJSON(b []byte) error { + var v string + if err := json.Unmarshal(b, &v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_Issue6NameUse_2 { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Issue6NameUse_2, v) + } + *j = Issue6NameUse_2(v) + return nil +} + +// Something +type Period interface{} diff --git a/tests/data/core/allOf/issue6.json b/tests/data/core/allOf/issue6.json new file mode 100644 index 00000000..c2bf6f26 --- /dev/null +++ b/tests/data/core/allOf/issue6.json @@ -0,0 +1,130 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "id": "http://hl7.org/fhir/json-schema/HumanName", + "type": "object", + "properties": { + "name": { + "description": "A human\u0027s name with the ability to identify parts and usage.", + "type": "object", + "properties": { + "use": { + "description": "Identifies the purpose for this name.", + "enum": [ + "usual", + "official", + "temp", + "nickname", + "anonymous", + "old", + "maiden" + ], + "type": "string" + }, + "_use": { + "description": "Extensions for use", + "$ref": "#/$defs/Element" + }, + "text": { + "description": "A full text representation of the name.", + "type": "string" + }, + "_text": { + "description": "Extensions for text", + "$ref": "#/$defs/Element" + }, + "family": { + "description": "The part of a name that links to the genealogy. In some cultures (e.g. Eritrea) the family name of a son is the first name of his father.", + "type": "string" + }, + "_family": { + "description": "Extensions for family", + "$ref": "#/$defs/Element" + }, + "given": { + "description": "Given name.", + "type": "array", + "items": { + "type": "string" + } + }, + "_given": { + "description": "Extensions for given", + "type": "array", + "items": { + "$ref": "#/$defs/Element" + } + }, + "prefix": { + "description": "Part of the name that is acquired as a title due to academic, legal, employment or nobility status, etc. and that appears at the start of the name.", + "type": "array", + "items": { + "type": "string" + } + }, + "_prefix": { + "description": "Extensions for prefix", + "type": "array", + "items": { + "$ref": "#/$defs/Element" + } + }, + "suffix": { + "description": "Part of the name that is acquired as a title due to academic, legal, employment or nobility status, etc. and that appears at the end of the name.", + "type": "array", + "items": { + "type": "string" + } + }, + "_suffix": { + "description": "Extensions for suffix", + "type": "array", + "items": { + "$ref": "#/$defs/Element" + } + }, + "period": { + "description": "Indicates the period of time when this name was valid for the named person.", + "$ref": "#/$defs/Period" + } + } + } + }, + "description": "see http://hl7.org/fhir/json.html#schema for information about the FHIR Json Schemas", + "$defs": { + "Period": { + "description": "Something", + "properties": { + "start": { + "description": "The start of the period. The boundary is inclusive.", + "type": "string", + "format": "date-time" + }, + "end": { + "description": "The end of the period. If the end of the period is missing, it means that the period is ongoing.", + "type": "string", + "format": "date-time" + } + } + }, + "Element": { + "description": "Base definition for all elements in a resource.", + "properties": { + "id": { + "description": "Unique id for the element within a resource (for internal references).", + "type": "string" + }, + "name": { + "description": "Name for the element", + "type": "string" + }, + "extension": { + "description": "Additional content defined by implementations.", + "type": "array", + "items": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/data/core/anyOf/anyOf.go b/tests/data/core/anyOf/anyOf.go index 358396a1..8ee46c8a 100644 --- a/tests/data/core/anyOf/anyOf.go +++ b/tests/data/core/anyOf/anyOf.go @@ -31,41 +31,77 @@ type AnyOfConfigurationsElem_0 struct { Foo string `json:"foo" yaml:"foo" mapstructure:"foo"` } +// UnmarshalJSON implements json.Unmarshaler. +func (j *AnyOfConfigurationsElem_0) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if _, ok := raw["foo"]; raw != nil && !ok { + return fmt.Errorf("field foo in AnyOfConfigurationsElem_0: required") + } + type Plain AnyOfConfigurationsElem_0 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_0(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AnyOfConfigurationsElem_0) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["foo"]; raw != nil && !ok { + return fmt.Errorf("field foo in AnyOfConfigurationsElem_0: required") + } + type Plain AnyOfConfigurationsElem_0 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = AnyOfConfigurationsElem_0(plain) + return nil +} + type AnyOfConfigurationsElem_1 struct { // Bar corresponds to the JSON schema field "bar". Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` } -// UnmarshalJSON implements json.Unmarshaler. -func (j *AnyOfConfigurationsElem_1) UnmarshalJSON(value []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *AnyOfConfigurationsElem_1) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { + if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["bar"]; !ok || v == nil { + if _, ok := raw["bar"]; raw != nil && !ok { return fmt.Errorf("field bar in AnyOfConfigurationsElem_1: required") } type Plain AnyOfConfigurationsElem_1 var plain Plain - if err := json.Unmarshal(value, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } *j = AnyOfConfigurationsElem_1(plain) return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *AnyOfConfigurationsElem_1) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *AnyOfConfigurationsElem_1) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } - if v, ok := raw["bar"]; !ok || v == nil { + if _, ok := raw["bar"]; raw != nil && !ok { return fmt.Errorf("field bar in AnyOfConfigurationsElem_1: required") } type Plain AnyOfConfigurationsElem_1 var plain Plain - if err := value.Decode(&plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } *j = AnyOfConfigurationsElem_1(plain) @@ -107,24 +143,6 @@ func (j *AnyOfConfigurationsElem_2) UnmarshalYAML(value *yaml.Node) error { return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *AnyOfConfigurationsElem_0) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } - if v, ok := raw["foo"]; !ok || v == nil { - return fmt.Errorf("field foo in AnyOfConfigurationsElem_0: required") - } - type Plain AnyOfConfigurationsElem_0 - var plain Plain - if err := value.Decode(&plain); err != nil { - return err - } - *j = AnyOfConfigurationsElem_0(plain) - return nil -} - // UnmarshalJSON implements json.Unmarshaler. func (j *AnyOfConfigurationsElem) UnmarshalJSON(value []byte) error { var raw map[string]interface{} @@ -186,21 +204,3 @@ func (j *AnyOfConfigurationsElem) UnmarshalYAML(value *yaml.Node) error { *j = AnyOfConfigurationsElem(plain) return nil } - -// UnmarshalJSON implements json.Unmarshaler. -func (j *AnyOfConfigurationsElem_0) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } - if v, ok := raw["foo"]; !ok || v == nil { - return fmt.Errorf("field foo in AnyOfConfigurationsElem_0: required") - } - type Plain AnyOfConfigurationsElem_0 - var plain Plain - if err := json.Unmarshal(value, &plain); err != nil { - return err - } - *j = AnyOfConfigurationsElem_0(plain) - return nil -} diff --git a/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go index af6be8c3..81a1ec68 100644 --- a/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go +++ b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go @@ -24,6 +24,84 @@ type DecoratedPlannerDecorator struct { Theme *string `json:"theme,omitempty" yaml:"theme,omitempty" mapstructure:"theme,omitempty"` } +// UnmarshalJSON implements json.Unmarshaler. +func (j *DecoratedPlannerDecorator) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain DecoratedPlannerDecorator + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["color"]; !ok || v == nil { + plain.Color = "#ffffff" + } + *j = DecoratedPlannerDecorator(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *DecoratedPlannerDecorator) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain DecoratedPlannerDecorator + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if v, ok := raw["color"]; !ok || v == nil { + plain.Color = "#ffffff" + } + *j = DecoratedPlannerDecorator(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *DecoratedPlanner) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain DecoratedPlanner + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if v, ok := raw["decorator"]; !ok || v == nil { + plain.Decorator = DecoratedPlannerDecorator{ + Color: "#ffffff", + Theme: nil, + } + } + *j = DecoratedPlanner(plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *DecoratedPlanner) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + type Plain DecoratedPlanner + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw["decorator"]; !ok || v == nil { + plain.Decorator = DecoratedPlannerDecorator{ + Color: "#ffffff", + Theme: nil, + } + } + *j = DecoratedPlanner(plain) + return nil +} + type DefaultPlanner struct { // Event corresponds to the JSON schema field "event". Event *Event `json:"event,omitempty" yaml:"event,omitempty" mapstructure:"event,omitempty"` @@ -41,29 +119,38 @@ type EventName string const EventNameBIRTHDAY EventName = "BIRTHDAY" const EventNameGAME EventName = "GAME" +const EventNameHOLIDAY EventName = "HOLIDAY" -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *DecoratedPlannerDecorator) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { +var enumValues_EventName = []interface{}{ + "BIRTHDAY", + "GAME", + "HOLIDAY", +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *EventName) UnmarshalJSON(b []byte) error { + var v string + if err := json.Unmarshal(b, &v); err != nil { return err } - type Plain DecoratedPlannerDecorator - var plain Plain - if err := value.Decode(&plain); err != nil { - return err + var ok bool + for _, expected := range enumValues_EventName { + if reflect.DeepEqual(v, expected) { + ok = true + break + } } - if v, ok := raw["color"]; !ok || v == nil { - plain.Color = "#ffffff" + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EventName, v) } - *j = DecoratedPlannerDecorator(plain) + *j = EventName(v) return nil } -// UnmarshalJSON implements json.Unmarshaler. -func (j *EventName) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EventName) UnmarshalYAML(value *yaml.Node) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := value.Decode(&v); err != nil { return err } var ok bool @@ -80,10 +167,13 @@ func (j *EventName) UnmarshalJSON(b []byte) error { return nil } -const EventNameHOLIDAY EventName = "HOLIDAY" - type EventTagsElem string +const EventTagsElemCITY EventTagsElem = "CITY" +const EventTagsElemCOUNTRY EventTagsElem = "COUNTRY" +const EventTagsElemPERSON EventTagsElem = "PERSON" +const EventTagsElemREGION EventTagsElem = "REGION" + var enumValues_EventTagsElem = []interface{}{ "COUNTRY", "REGION", @@ -91,10 +181,10 @@ var enumValues_EventTagsElem = []interface{}{ "PERSON", } -// UnmarshalJSON implements json.Unmarshaler. -func (j *EventTagsElem) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EventTagsElem) UnmarshalYAML(value *yaml.Node) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := value.Decode(&v); err != nil { return err } var ok bool @@ -111,10 +201,10 @@ func (j *EventTagsElem) UnmarshalJSON(b []byte) error { return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *EventTagsElem) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *EventTagsElem) UnmarshalJSON(b []byte) error { var v string - if err := value.Decode(&v); err != nil { + if err := json.Unmarshal(b, &v); err != nil { return err } var ok bool @@ -131,17 +221,6 @@ func (j *EventTagsElem) UnmarshalYAML(value *yaml.Node) error { return nil } -const EventTagsElemCOUNTRY EventTagsElem = "COUNTRY" -const EventTagsElemREGION EventTagsElem = "REGION" -const EventTagsElemCITY EventTagsElem = "CITY" -const EventTagsElemPERSON EventTagsElem = "PERSON" - -var enumValues_EventName = []interface{}{ - "BIRTHDAY", - "GAME", - "HOLIDAY", -} - // UnmarshalJSON implements json.Unmarshaler. func (j *Event) UnmarshalJSON(value []byte) error { var raw map[string]interface{} @@ -178,84 +257,20 @@ func (j *Event) UnmarshalYAML(value *yaml.Node) error { return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *EventName) UnmarshalYAML(value *yaml.Node) error { - var v string - if err := value.Decode(&v); err != nil { - return err - } - var ok bool - for _, expected := range enumValues_EventName { - if reflect.DeepEqual(v, expected) { - ok = true - break - } - } - if !ok { - return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_EventName, v) - } - *j = EventName(v) - return nil -} +type ObjectPropertiesDefault struct { + // Active corresponds to the JSON schema field "active". + Active interface{} `json:"active,omitempty" yaml:"active,omitempty" mapstructure:"active,omitempty"` -// UnmarshalJSON implements json.Unmarshaler. -func (j *DecoratedPlanner) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } - type Plain DecoratedPlanner - var plain Plain - if err := json.Unmarshal(value, &plain); err != nil { - return err - } - if v, ok := raw["decorator"]; !ok || v == nil { - plain.Decorator = DecoratedPlannerDecorator{ - Color: "#ffffff", - Theme: nil, - } - } - *j = DecoratedPlanner(plain) - return nil + // Planners corresponds to the JSON schema field "planners". + Planners []ObjectPropertiesDefaultPlannersElem `json:"planners,omitempty" yaml:"planners,omitempty" mapstructure:"planners,omitempty"` } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *DecoratedPlanner) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } - type Plain DecoratedPlanner - var plain Plain - if err := value.Decode(&plain); err != nil { - return err - } - if v, ok := raw["decorator"]; !ok || v == nil { - plain.Decorator = DecoratedPlannerDecorator{ - Color: "#ffffff", - Theme: nil, - } - } - *j = DecoratedPlanner(plain) - return nil -} +type ObjectPropertiesDefaultPlannersElem struct { + // Decorated corresponds to the JSON schema field "decorated". + Decorated *DecoratedPlanner `json:"decorated,omitempty" yaml:"decorated,omitempty" mapstructure:"decorated,omitempty"` -// UnmarshalJSON implements json.Unmarshaler. -func (j *DecoratedPlannerDecorator) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } - type Plain DecoratedPlannerDecorator - var plain Plain - if err := json.Unmarshal(value, &plain); err != nil { - return err - } - if v, ok := raw["color"]; !ok || v == nil { - plain.Color = "#ffffff" - } - *j = DecoratedPlannerDecorator(plain) - return nil + // Plain corresponds to the JSON schema field "plain". + Plain *DefaultPlanner `json:"plain,omitempty" yaml:"plain,omitempty" mapstructure:"plain,omitempty"` } type ObjectPropertiesDefaultPlannersElem_0 struct { @@ -263,30 +278,30 @@ type ObjectPropertiesDefaultPlannersElem_0 struct { Plain *DefaultPlanner `json:"plain,omitempty" yaml:"plain,omitempty" mapstructure:"plain,omitempty"` } -// UnmarshalJSON implements json.Unmarshaler. -func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalJSON(value []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { + if err := value.Decode(&raw); err != nil { return err } type Plain ObjectPropertiesDefaultPlannersElem_0 var plain Plain - if err := json.Unmarshal(value, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } *j = ObjectPropertiesDefaultPlannersElem_0(plain) return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain ObjectPropertiesDefaultPlannersElem_0 var plain Plain - if err := value.Decode(&plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } *j = ObjectPropertiesDefaultPlannersElem_0(plain) @@ -328,14 +343,6 @@ func (j *ObjectPropertiesDefaultPlannersElem_1) UnmarshalYAML(value *yaml.Node) return nil } -type ObjectPropertiesDefaultPlannersElem struct { - // Decorated corresponds to the JSON schema field "decorated". - Decorated *DecoratedPlanner `json:"decorated,omitempty" yaml:"decorated,omitempty" mapstructure:"decorated,omitempty"` - - // Plain corresponds to the JSON schema field "plain". - Plain *DefaultPlanner `json:"plain,omitempty" yaml:"plain,omitempty" mapstructure:"plain,omitempty"` -} - // UnmarshalJSON implements json.Unmarshaler. func (j *ObjectPropertiesDefaultPlannersElem) UnmarshalJSON(value []byte) error { var raw map[string]interface{} @@ -389,11 +396,3 @@ func (j *ObjectPropertiesDefaultPlannersElem) UnmarshalYAML(value *yaml.Node) er *j = ObjectPropertiesDefaultPlannersElem(plain) return nil } - -type ObjectPropertiesDefault struct { - // Active corresponds to the JSON schema field "active". - Active interface{} `json:"active,omitempty" yaml:"active,omitempty" mapstructure:"active,omitempty"` - - // Planners corresponds to the JSON schema field "planners". - Planners []ObjectPropertiesDefaultPlannersElem `json:"planners,omitempty" yaml:"planners,omitempty" mapstructure:"planners,omitempty"` -} diff --git a/tests/data/misc/specialCharacters/specialCharacters.go b/tests/data/misc/specialCharacters/specialCharacters.go index da25bfaa..27b0f929 100644 --- a/tests/data/misc/specialCharacters/specialCharacters.go +++ b/tests/data/misc/specialCharacters/specialCharacters.go @@ -12,44 +12,61 @@ type License string const LicenseGPL30 License = "GPL-3.0" const LicenseMIT License = "MIT" -type SpecialCharacters struct { - // PlainLicenses corresponds to the JSON schema field "plainLicenses". - PlainLicenses *SpecialCharactersPlainLicenses `json:"plainLicenses,omitempty" yaml:"plainLicenses,omitempty" mapstructure:"plainLicenses,omitempty"` - - // PlainLicensesRef corresponds to the JSON schema field "plainLicensesRef". - PlainLicensesRef []License `json:"plainLicensesRef,omitempty" yaml:"plainLicensesRef,omitempty" mapstructure:"plainLicensesRef,omitempty"` +type License_1 string - // PlusLicenses corresponds to the JSON schema field "plusLicenses". - PlusLicenses *SpecialCharactersPlusLicenses `json:"plusLicenses,omitempty" yaml:"plusLicenses,omitempty" mapstructure:"plusLicenses,omitempty"` +const License_1_GPL30 License_1 = "GPL-3.0+" +const License_1_MIT License_1 = "MIT+" - // PlusLicensesRef corresponds to the JSON schema field "plusLicensesRef". - PlusLicensesRef []License `json:"plusLicensesRef,omitempty" yaml:"plusLicensesRef,omitempty" mapstructure:"plusLicensesRef,omitempty"` +var enumValues_License_1 = []interface{}{ + "GPL-3.0+", + "MIT+", } -type SpecialCharactersPlainLicenses string - -const SpecialCharactersPlainLicensesGPL30 SpecialCharactersPlainLicenses = "GPL-3.0" +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *License_1) UnmarshalYAML(value *yaml.Node) error { + var v string + if err := value.Decode(&v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_License_1 { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_License_1, v) + } + *j = License_1(v) + return nil +} // UnmarshalJSON implements json.Unmarshaler. -func (j *License) UnmarshalJSON(b []byte) error { +func (j *License_1) UnmarshalJSON(b []byte) error { var v string if err := json.Unmarshal(b, &v); err != nil { return err } var ok bool - for _, expected := range enumValues_License { + for _, expected := range enumValues_License_1 { if reflect.DeepEqual(v, expected) { ok = true break } } if !ok { - return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_License, v) + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_License_1, v) } - *j = License(v) + *j = License_1(v) return nil } +var enumValues_License = []interface{}{ + "GPL-3.0", + "MIT", +} + // UnmarshalYAML implements yaml.Unmarshaler. func (j *License) UnmarshalYAML(value *yaml.Node) error { var v string @@ -70,6 +87,43 @@ func (j *License) UnmarshalYAML(value *yaml.Node) error { return nil } +// UnmarshalJSON implements json.Unmarshaler. +func (j *License) UnmarshalJSON(b []byte) error { + var v string + if err := json.Unmarshal(b, &v); err != nil { + return err + } + var ok bool + for _, expected := range enumValues_License { + if reflect.DeepEqual(v, expected) { + ok = true + break + } + } + if !ok { + return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_License, v) + } + *j = License(v) + return nil +} + +type SpecialCharacters struct { + // PlainLicenses corresponds to the JSON schema field "plainLicenses". + PlainLicenses *SpecialCharactersPlainLicenses `json:"plainLicenses,omitempty" yaml:"plainLicenses,omitempty" mapstructure:"plainLicenses,omitempty"` + + // PlainLicensesRef corresponds to the JSON schema field "plainLicensesRef". + PlainLicensesRef []License `json:"plainLicensesRef,omitempty" yaml:"plainLicensesRef,omitempty" mapstructure:"plainLicensesRef,omitempty"` + + // PlusLicenses corresponds to the JSON schema field "plusLicenses". + PlusLicenses *SpecialCharactersPlusLicenses `json:"plusLicenses,omitempty" yaml:"plusLicenses,omitempty" mapstructure:"plusLicenses,omitempty"` + + // PlusLicensesRef corresponds to the JSON schema field "plusLicensesRef". + PlusLicensesRef []License_1 `json:"plusLicensesRef,omitempty" yaml:"plusLicensesRef,omitempty" mapstructure:"plusLicensesRef,omitempty"` +} + +type SpecialCharactersPlainLicenses string + +const SpecialCharactersPlainLicensesGPL30 SpecialCharactersPlainLicenses = "GPL-3.0" const SpecialCharactersPlainLicensesMIT SpecialCharactersPlainLicenses = "MIT" var enumValues_SpecialCharactersPlainLicenses = []interface{}{ @@ -97,8 +151,6 @@ func (j *SpecialCharactersPlainLicenses) UnmarshalJSON(b []byte) error { return nil } -type SpecialCharactersPlusLicenses string - // UnmarshalYAML implements yaml.Unmarshaler. func (j *SpecialCharactersPlainLicenses) UnmarshalYAML(value *yaml.Node) error { var v string @@ -119,6 +171,11 @@ func (j *SpecialCharactersPlainLicenses) UnmarshalYAML(value *yaml.Node) error { return nil } +type SpecialCharactersPlusLicenses string + +const SpecialCharactersPlusLicensesGPL30 SpecialCharactersPlusLicenses = "GPL-3.0+" +const SpecialCharactersPlusLicensesMIT SpecialCharactersPlusLicenses = "MIT+" + var enumValues_SpecialCharactersPlusLicenses = []interface{}{ "GPL-3.0+", "MIT+", @@ -163,11 +220,3 @@ func (j *SpecialCharactersPlusLicenses) UnmarshalYAML(value *yaml.Node) error { *j = SpecialCharactersPlusLicenses(v) return nil } - -const SpecialCharactersPlusLicensesGPL30 SpecialCharactersPlusLicenses = "GPL-3.0+" -const SpecialCharactersPlusLicensesMIT SpecialCharactersPlusLicenses = "MIT+" - -var enumValues_License = []interface{}{ - "GPL-3.0", - "MIT", -} diff --git a/tests/data/validation/enum/enum.go b/tests/data/validation/enum/enum.go index 3377e20f..ec2f692d 100644 --- a/tests/data/validation/enum/enum.go +++ b/tests/data/validation/enum/enum.go @@ -7,6 +7,42 @@ import "fmt" import yaml "gopkg.in/yaml.v3" import "reflect" +type Enum struct { + // MyBooleanTypedEnum corresponds to the JSON schema field "myBooleanTypedEnum". + MyBooleanTypedEnum *EnumMyBooleanTypedEnum `json:"myBooleanTypedEnum,omitempty" yaml:"myBooleanTypedEnum,omitempty" mapstructure:"myBooleanTypedEnum,omitempty"` + + // MyBooleanUntypedEnum corresponds to the JSON schema field + // "myBooleanUntypedEnum". + MyBooleanUntypedEnum *EnumMyBooleanUntypedEnum `json:"myBooleanUntypedEnum,omitempty" yaml:"myBooleanUntypedEnum,omitempty" mapstructure:"myBooleanUntypedEnum,omitempty"` + + // MyIntegerTypedEnum corresponds to the JSON schema field "myIntegerTypedEnum". + MyIntegerTypedEnum *EnumMyIntegerTypedEnum `json:"myIntegerTypedEnum,omitempty" yaml:"myIntegerTypedEnum,omitempty" mapstructure:"myIntegerTypedEnum,omitempty"` + + // MyMixedTypeEnum corresponds to the JSON schema field "myMixedTypeEnum". + MyMixedTypeEnum *EnumMyMixedTypeEnum `json:"myMixedTypeEnum,omitempty" yaml:"myMixedTypeEnum,omitempty" mapstructure:"myMixedTypeEnum,omitempty"` + + // MyMixedUntypedEnum corresponds to the JSON schema field "myMixedUntypedEnum". + MyMixedUntypedEnum *EnumMyMixedUntypedEnum `json:"myMixedUntypedEnum,omitempty" yaml:"myMixedUntypedEnum,omitempty" mapstructure:"myMixedUntypedEnum,omitempty"` + + // MyNullTypedEnum corresponds to the JSON schema field "myNullTypedEnum". + MyNullTypedEnum *EnumMyNullTypedEnum `json:"myNullTypedEnum,omitempty" yaml:"myNullTypedEnum,omitempty" mapstructure:"myNullTypedEnum,omitempty"` + + // MyNullUntypedEnum corresponds to the JSON schema field "myNullUntypedEnum". + MyNullUntypedEnum *EnumMyNullUntypedEnum `json:"myNullUntypedEnum,omitempty" yaml:"myNullUntypedEnum,omitempty" mapstructure:"myNullUntypedEnum,omitempty"` + + // MyNumberTypedEnum corresponds to the JSON schema field "myNumberTypedEnum". + MyNumberTypedEnum *EnumMyNumberTypedEnum `json:"myNumberTypedEnum,omitempty" yaml:"myNumberTypedEnum,omitempty" mapstructure:"myNumberTypedEnum,omitempty"` + + // MyNumberUntypedEnum corresponds to the JSON schema field "myNumberUntypedEnum". + MyNumberUntypedEnum *EnumMyNumberUntypedEnum `json:"myNumberUntypedEnum,omitempty" yaml:"myNumberUntypedEnum,omitempty" mapstructure:"myNumberUntypedEnum,omitempty"` + + // MyStringTypedEnum corresponds to the JSON schema field "myStringTypedEnum". + MyStringTypedEnum *EnumMyStringTypedEnum `json:"myStringTypedEnum,omitempty" yaml:"myStringTypedEnum,omitempty" mapstructure:"myStringTypedEnum,omitempty"` + + // MyStringUntypedEnum corresponds to the JSON schema field "myStringUntypedEnum". + MyStringUntypedEnum *EnumMyStringUntypedEnum `json:"myStringUntypedEnum,omitempty" yaml:"myStringUntypedEnum,omitempty" mapstructure:"myStringUntypedEnum,omitempty"` +} + type EnumMyBooleanTypedEnum bool var enumValues_EnumMyBooleanTypedEnum = []interface{}{ @@ -153,22 +189,27 @@ type EnumMyMixedTypeEnum struct { Value interface{} } -var enumValues_EnumMyMixedTypeEnum = []interface{}{ - 42.0, - "smurf", -} - // MarshalJSON implements json.Marshaler. func (j *EnumMyMixedTypeEnum) MarshalJSON() ([]byte, error) { return json.Marshal(j.Value) } -// UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyMixedTypeEnum) UnmarshalJSON(b []byte) error { +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyMixedTypeEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + +var enumValues_EnumMyMixedTypeEnum = []interface{}{ + 42.0, + "smurf", +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyMixedTypeEnum) UnmarshalYAML(value *yaml.Node) error { var v struct { Value interface{} } - if err := json.Unmarshal(b, &v.Value); err != nil { + if err := value.Decode(&v.Value); err != nil { return err } var ok bool @@ -185,17 +226,12 @@ func (j *EnumMyMixedTypeEnum) UnmarshalJSON(b []byte) error { return nil } -// MarshalYAML implements yaml.Marshal. -func (j *EnumMyMixedTypeEnum) MarshalYAML() (interface{}, error) { - return yaml.Marshal(j.Value) -} - -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *EnumMyMixedTypeEnum) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *EnumMyMixedTypeEnum) UnmarshalJSON(b []byte) error { var v struct { Value interface{} } - if err := value.Decode(&v.Value); err != nil { + if err := json.Unmarshal(b, &v.Value); err != nil { return err } var ok bool @@ -216,6 +252,16 @@ type EnumMyMixedUntypedEnum struct { Value interface{} } +// MarshalJSON implements json.Marshaler. +func (j *EnumMyMixedUntypedEnum) MarshalJSON() ([]byte, error) { + return json.Marshal(j.Value) +} + +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyMixedUntypedEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + var enumValues_EnumMyMixedUntypedEnum = []interface{}{ "red", 1.0, @@ -223,11 +269,6 @@ var enumValues_EnumMyMixedUntypedEnum = []interface{}{ nil, } -// MarshalJSON implements json.Marshaler. -func (j *EnumMyMixedUntypedEnum) MarshalJSON() ([]byte, error) { - return json.Marshal(j.Value) -} - // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyMixedUntypedEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -250,11 +291,6 @@ func (j *EnumMyMixedUntypedEnum) UnmarshalJSON(b []byte) error { return nil } -// MarshalYAML implements yaml.Marshal. -func (j *EnumMyMixedUntypedEnum) MarshalYAML() (interface{}, error) { - return yaml.Marshal(j.Value) -} - // UnmarshalYAML implements yaml.Unmarshaler. func (j *EnumMyMixedUntypedEnum) UnmarshalYAML(value *yaml.Node) error { var v struct { @@ -281,15 +317,20 @@ type EnumMyNullTypedEnum struct { Value interface{} } -var enumValues_EnumMyNullTypedEnum = []interface{}{ - nil, -} - // MarshalJSON implements json.Marshaler. func (j *EnumMyNullTypedEnum) MarshalJSON() ([]byte, error) { return json.Marshal(j.Value) } +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyNullTypedEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + +var enumValues_EnumMyNullTypedEnum = []interface{}{ + nil, +} + // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyNullTypedEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -312,11 +353,6 @@ func (j *EnumMyNullTypedEnum) UnmarshalJSON(b []byte) error { return nil } -// MarshalYAML implements yaml.Marshal. -func (j *EnumMyNullTypedEnum) MarshalYAML() (interface{}, error) { - return yaml.Marshal(j.Value) -} - // UnmarshalYAML implements yaml.Unmarshaler. func (j *EnumMyNullTypedEnum) UnmarshalYAML(value *yaml.Node) error { var v struct { @@ -339,10 +375,6 @@ func (j *EnumMyNullTypedEnum) UnmarshalYAML(value *yaml.Node) error { return nil } -var enumValues_EnumMyNullUntypedEnum = []interface{}{ - nil, -} - type EnumMyNullUntypedEnum struct { Value interface{} } @@ -352,6 +384,15 @@ func (j *EnumMyNullUntypedEnum) MarshalJSON() ([]byte, error) { return json.Marshal(j.Value) } +// MarshalYAML implements yaml.Marshal. +func (j *EnumMyNullUntypedEnum) MarshalYAML() (interface{}, error) { + return yaml.Marshal(j.Value) +} + +var enumValues_EnumMyNullUntypedEnum = []interface{}{ + nil, +} + // UnmarshalJSON implements json.Unmarshaler. func (j *EnumMyNullUntypedEnum) UnmarshalJSON(b []byte) error { var v struct { @@ -374,11 +415,6 @@ func (j *EnumMyNullUntypedEnum) UnmarshalJSON(b []byte) error { return nil } -// MarshalYAML implements yaml.Marshal. -func (j *EnumMyNullUntypedEnum) MarshalYAML() (interface{}, error) { - return yaml.Marshal(j.Value) -} - // UnmarshalYAML implements yaml.Unmarshaler. func (j *EnumMyNullUntypedEnum) UnmarshalYAML(value *yaml.Node) error { var v struct { @@ -499,6 +535,10 @@ func (j *EnumMyNumberUntypedEnum) UnmarshalYAML(value *yaml.Node) error { type EnumMyStringTypedEnum string +const EnumMyStringTypedEnumBlue EnumMyStringTypedEnum = "blue" +const EnumMyStringTypedEnumGreen EnumMyStringTypedEnum = "green" +const EnumMyStringTypedEnumRed EnumMyStringTypedEnum = "red" + var enumValues_EnumMyStringTypedEnum = []interface{}{ "red", "blue", @@ -545,22 +585,22 @@ func (j *EnumMyStringTypedEnum) UnmarshalYAML(value *yaml.Node) error { return nil } -const EnumMyStringTypedEnumBlue EnumMyStringTypedEnum = "blue" -const EnumMyStringTypedEnumGreen EnumMyStringTypedEnum = "green" -const EnumMyStringTypedEnumRed EnumMyStringTypedEnum = "red" - type EnumMyStringUntypedEnum string +const EnumMyStringUntypedEnumBlue EnumMyStringUntypedEnum = "blue" +const EnumMyStringUntypedEnumGreen EnumMyStringUntypedEnum = "green" +const EnumMyStringUntypedEnumRed EnumMyStringUntypedEnum = "red" + var enumValues_EnumMyStringUntypedEnum = []interface{}{ "red", "blue", "green", } -// UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyStringUntypedEnum) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *EnumMyStringUntypedEnum) UnmarshalYAML(value *yaml.Node) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := value.Decode(&v); err != nil { return err } var ok bool @@ -577,10 +617,10 @@ func (j *EnumMyStringUntypedEnum) UnmarshalJSON(b []byte) error { return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *EnumMyStringUntypedEnum) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *EnumMyStringUntypedEnum) UnmarshalJSON(b []byte) error { var v string - if err := value.Decode(&v); err != nil { + if err := json.Unmarshal(b, &v); err != nil { return err } var ok bool @@ -596,43 +636,3 @@ func (j *EnumMyStringUntypedEnum) UnmarshalYAML(value *yaml.Node) error { *j = EnumMyStringUntypedEnum(v) return nil } - -type Enum struct { - // MyBooleanTypedEnum corresponds to the JSON schema field "myBooleanTypedEnum". - MyBooleanTypedEnum *EnumMyBooleanTypedEnum `json:"myBooleanTypedEnum,omitempty" yaml:"myBooleanTypedEnum,omitempty" mapstructure:"myBooleanTypedEnum,omitempty"` - - // MyBooleanUntypedEnum corresponds to the JSON schema field - // "myBooleanUntypedEnum". - MyBooleanUntypedEnum *EnumMyBooleanUntypedEnum `json:"myBooleanUntypedEnum,omitempty" yaml:"myBooleanUntypedEnum,omitempty" mapstructure:"myBooleanUntypedEnum,omitempty"` - - // MyIntegerTypedEnum corresponds to the JSON schema field "myIntegerTypedEnum". - MyIntegerTypedEnum *EnumMyIntegerTypedEnum `json:"myIntegerTypedEnum,omitempty" yaml:"myIntegerTypedEnum,omitempty" mapstructure:"myIntegerTypedEnum,omitempty"` - - // MyMixedTypeEnum corresponds to the JSON schema field "myMixedTypeEnum". - MyMixedTypeEnum *EnumMyMixedTypeEnum `json:"myMixedTypeEnum,omitempty" yaml:"myMixedTypeEnum,omitempty" mapstructure:"myMixedTypeEnum,omitempty"` - - // MyMixedUntypedEnum corresponds to the JSON schema field "myMixedUntypedEnum". - MyMixedUntypedEnum *EnumMyMixedUntypedEnum `json:"myMixedUntypedEnum,omitempty" yaml:"myMixedUntypedEnum,omitempty" mapstructure:"myMixedUntypedEnum,omitempty"` - - // MyNullTypedEnum corresponds to the JSON schema field "myNullTypedEnum". - MyNullTypedEnum *EnumMyNullTypedEnum `json:"myNullTypedEnum,omitempty" yaml:"myNullTypedEnum,omitempty" mapstructure:"myNullTypedEnum,omitempty"` - - // MyNullUntypedEnum corresponds to the JSON schema field "myNullUntypedEnum". - MyNullUntypedEnum *EnumMyNullUntypedEnum `json:"myNullUntypedEnum,omitempty" yaml:"myNullUntypedEnum,omitempty" mapstructure:"myNullUntypedEnum,omitempty"` - - // MyNumberTypedEnum corresponds to the JSON schema field "myNumberTypedEnum". - MyNumberTypedEnum *EnumMyNumberTypedEnum `json:"myNumberTypedEnum,omitempty" yaml:"myNumberTypedEnum,omitempty" mapstructure:"myNumberTypedEnum,omitempty"` - - // MyNumberUntypedEnum corresponds to the JSON schema field "myNumberUntypedEnum". - MyNumberUntypedEnum *EnumMyNumberUntypedEnum `json:"myNumberUntypedEnum,omitempty" yaml:"myNumberUntypedEnum,omitempty" mapstructure:"myNumberUntypedEnum,omitempty"` - - // MyStringTypedEnum corresponds to the JSON schema field "myStringTypedEnum". - MyStringTypedEnum *EnumMyStringTypedEnum `json:"myStringTypedEnum,omitempty" yaml:"myStringTypedEnum,omitempty" mapstructure:"myStringTypedEnum,omitempty"` - - // MyStringUntypedEnum corresponds to the JSON schema field "myStringUntypedEnum". - MyStringUntypedEnum *EnumMyStringUntypedEnum `json:"myStringUntypedEnum,omitempty" yaml:"myStringUntypedEnum,omitempty" mapstructure:"myStringUntypedEnum,omitempty"` -} - -const EnumMyStringUntypedEnumBlue EnumMyStringUntypedEnum = "blue" -const EnumMyStringUntypedEnumGreen EnumMyStringUntypedEnum = "green" -const EnumMyStringUntypedEnumRed EnumMyStringUntypedEnum = "red" diff --git a/tests/data/validation/maxLength/maxLength.go b/tests/data/validation/maxLength/maxLength.go index ca734ecd..5a1ee4b5 100644 --- a/tests/data/validation/maxLength/maxLength.go +++ b/tests/data/validation/maxLength/maxLength.go @@ -44,7 +44,7 @@ func (j *MaxLength) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myString"]; !ok || v == nil { + if _, ok := raw["myString"]; raw != nil && !ok { return fmt.Errorf("field myString in MaxLength: required") } type Plain MaxLength diff --git a/tests/data/validation/minLength/minLength.go b/tests/data/validation/minLength/minLength.go index 1e18295f..5f5c8627 100644 --- a/tests/data/validation/minLength/minLength.go +++ b/tests/data/validation/minLength/minLength.go @@ -44,7 +44,7 @@ func (j *MinLength) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myString"]; !ok || v == nil { + if _, ok := raw["myString"]; raw != nil && !ok { return fmt.Errorf("field myString in MinLength: required") } type Plain MinLength diff --git a/tests/data/validation/requiredFields/requiredFields.go b/tests/data/validation/requiredFields/requiredFields.go index fef61227..8640ede6 100644 --- a/tests/data/validation/requiredFields/requiredFields.go +++ b/tests/data/validation/requiredFields/requiredFields.go @@ -6,128 +6,128 @@ import "encoding/json" import "fmt" import yaml "gopkg.in/yaml.v3" +type RequiredFields struct { + // MyBoolean corresponds to the JSON schema field "myBoolean". + MyBoolean bool `json:"myBoolean" yaml:"myBoolean" mapstructure:"myBoolean"` + + // MyBooleanArray corresponds to the JSON schema field "myBooleanArray". + MyBooleanArray []bool `json:"myBooleanArray" yaml:"myBooleanArray" mapstructure:"myBooleanArray"` + + // MyInteger corresponds to the JSON schema field "myInteger". + MyInteger *int `json:"myInteger,omitempty" yaml:"myInteger,omitempty" mapstructure:"myInteger,omitempty"` + + // MyIntegerArray corresponds to the JSON schema field "myIntegerArray". + MyIntegerArray []int `json:"myIntegerArray,omitempty" yaml:"myIntegerArray,omitempty" mapstructure:"myIntegerArray,omitempty"` + + // MyNull corresponds to the JSON schema field "myNull". + MyNull interface{} `json:"myNull" yaml:"myNull" mapstructure:"myNull"` + + // MyNullArray corresponds to the JSON schema field "myNullArray". + MyNullArray []interface{} `json:"myNullArray" yaml:"myNullArray" mapstructure:"myNullArray"` + + // MyNumber corresponds to the JSON schema field "myNumber". + MyNumber float64 `json:"myNumber" yaml:"myNumber" mapstructure:"myNumber"` + + // MyNumberArray corresponds to the JSON schema field "myNumberArray". + MyNumberArray []float64 `json:"myNumberArray" yaml:"myNumberArray" mapstructure:"myNumberArray"` + + // MyObject corresponds to the JSON schema field "myObject". + MyObject RequiredFieldsMyObject `json:"myObject" yaml:"myObject" mapstructure:"myObject"` + + // MyObjectArray corresponds to the JSON schema field "myObjectArray". + MyObjectArray []RequiredFieldsMyObjectArrayElem `json:"myObjectArray" yaml:"myObjectArray" mapstructure:"myObjectArray"` + + // MyString corresponds to the JSON schema field "myString". + MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` + + // MyStringArray corresponds to the JSON schema field "myStringArray". + MyStringArray []string `json:"myStringArray" yaml:"myStringArray" mapstructure:"myStringArray"` +} + type RequiredFieldsMyObject struct { // MyNestedObjectString corresponds to the JSON schema field // "myNestedObjectString". MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` } +type RequiredFieldsMyObjectArrayElem struct { + // MyNestedObjectString corresponds to the JSON schema field + // "myNestedObjectString". + MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` +} + // UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredFieldsMyObject) UnmarshalJSON(value []byte) error { +func (j *RequiredFieldsMyObjectArrayElem) UnmarshalJSON(value []byte) error { var raw map[string]interface{} if err := json.Unmarshal(value, &raw); err != nil { return err } - if v, ok := raw["myNestedObjectString"]; !ok || v == nil { - return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") + if _, ok := raw["myNestedObjectString"]; raw != nil && !ok { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") } - type Plain RequiredFieldsMyObject + type Plain RequiredFieldsMyObjectArrayElem var plain Plain if err := json.Unmarshal(value, &plain); err != nil { return err } - *j = RequiredFieldsMyObject(plain) + *j = RequiredFieldsMyObjectArrayElem(plain) return nil } // UnmarshalYAML implements yaml.Unmarshaler. -func (j *RequiredFieldsMyObject) UnmarshalYAML(value *yaml.Node) error { +func (j *RequiredFieldsMyObjectArrayElem) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myNestedObjectString"]; !ok || v == nil { - return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") + if _, ok := raw["myNestedObjectString"]; raw != nil && !ok { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") } - type Plain RequiredFieldsMyObject + type Plain RequiredFieldsMyObjectArrayElem var plain Plain if err := value.Decode(&plain); err != nil { return err } - *j = RequiredFieldsMyObject(plain) + *j = RequiredFieldsMyObjectArrayElem(plain) return nil } -type RequiredFieldsMyObjectArrayElem struct { - // MyNestedObjectString corresponds to the JSON schema field - // "myNestedObjectString". - MyNestedObjectString string `json:"myNestedObjectString" yaml:"myNestedObjectString" mapstructure:"myNestedObjectString"` -} - // UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredFieldsMyObjectArrayElem) UnmarshalJSON(value []byte) error { +func (j *RequiredFieldsMyObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} if err := json.Unmarshal(value, &raw); err != nil { return err } - if v, ok := raw["myNestedObjectString"]; !ok || v == nil { - return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") + if _, ok := raw["myNestedObjectString"]; raw != nil && !ok { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") } - type Plain RequiredFieldsMyObjectArrayElem + type Plain RequiredFieldsMyObject var plain Plain if err := json.Unmarshal(value, &plain); err != nil { return err } - *j = RequiredFieldsMyObjectArrayElem(plain) + *j = RequiredFieldsMyObject(plain) return nil } // UnmarshalYAML implements yaml.Unmarshaler. -func (j *RequiredFieldsMyObjectArrayElem) UnmarshalYAML(value *yaml.Node) error { +func (j *RequiredFieldsMyObject) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myNestedObjectString"]; !ok || v == nil { - return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObjectArrayElem: required") + if _, ok := raw["myNestedObjectString"]; raw != nil && !ok { + return fmt.Errorf("field myNestedObjectString in RequiredFieldsMyObject: required") } - type Plain RequiredFieldsMyObjectArrayElem + type Plain RequiredFieldsMyObject var plain Plain if err := value.Decode(&plain); err != nil { return err } - *j = RequiredFieldsMyObjectArrayElem(plain) + *j = RequiredFieldsMyObject(plain) return nil } -type RequiredFields struct { - // MyBoolean corresponds to the JSON schema field "myBoolean". - MyBoolean bool `json:"myBoolean" yaml:"myBoolean" mapstructure:"myBoolean"` - - // MyBooleanArray corresponds to the JSON schema field "myBooleanArray". - MyBooleanArray []bool `json:"myBooleanArray" yaml:"myBooleanArray" mapstructure:"myBooleanArray"` - - // MyInteger corresponds to the JSON schema field "myInteger". - MyInteger *int `json:"myInteger,omitempty" yaml:"myInteger,omitempty" mapstructure:"myInteger,omitempty"` - - // MyIntegerArray corresponds to the JSON schema field "myIntegerArray". - MyIntegerArray []int `json:"myIntegerArray,omitempty" yaml:"myIntegerArray,omitempty" mapstructure:"myIntegerArray,omitempty"` - - // MyNull corresponds to the JSON schema field "myNull". - MyNull interface{} `json:"myNull" yaml:"myNull" mapstructure:"myNull"` - - // MyNullArray corresponds to the JSON schema field "myNullArray". - MyNullArray []interface{} `json:"myNullArray" yaml:"myNullArray" mapstructure:"myNullArray"` - - // MyNumber corresponds to the JSON schema field "myNumber". - MyNumber float64 `json:"myNumber" yaml:"myNumber" mapstructure:"myNumber"` - - // MyNumberArray corresponds to the JSON schema field "myNumberArray". - MyNumberArray []float64 `json:"myNumberArray" yaml:"myNumberArray" mapstructure:"myNumberArray"` - - // MyObject corresponds to the JSON schema field "myObject". - MyObject RequiredFieldsMyObject `json:"myObject" yaml:"myObject" mapstructure:"myObject"` - - // MyObjectArray corresponds to the JSON schema field "myObjectArray". - MyObjectArray []RequiredFieldsMyObjectArrayElem `json:"myObjectArray" yaml:"myObjectArray" mapstructure:"myObjectArray"` - - // MyString corresponds to the JSON schema field "myString". - MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` - - // MyStringArray corresponds to the JSON schema field "myStringArray". - MyStringArray []string `json:"myStringArray" yaml:"myStringArray" mapstructure:"myStringArray"` -} - // UnmarshalJSON implements json.Unmarshaler. func (j *RequiredFields) UnmarshalJSON(value []byte) error { var raw map[string]interface{} @@ -187,34 +187,34 @@ func (j *RequiredFields) UnmarshalYAML(value *yaml.Node) error { if err := value.Decode(&raw); err != nil { return err } - if v, ok := raw["myBoolean"]; !ok || v == nil { + if _, ok := raw["myBoolean"]; raw != nil && !ok { return fmt.Errorf("field myBoolean in RequiredFields: required") } - if v, ok := raw["myBooleanArray"]; !ok || v == nil { + if _, ok := raw["myBooleanArray"]; raw != nil && !ok { return fmt.Errorf("field myBooleanArray in RequiredFields: required") } - if v, ok := raw["myNull"]; !ok || v == nil { + if _, ok := raw["myNull"]; raw != nil && !ok { return fmt.Errorf("field myNull in RequiredFields: required") } - if v, ok := raw["myNullArray"]; !ok || v == nil { + if _, ok := raw["myNullArray"]; raw != nil && !ok { return fmt.Errorf("field myNullArray in RequiredFields: required") } - if v, ok := raw["myNumber"]; !ok || v == nil { + if _, ok := raw["myNumber"]; raw != nil && !ok { return fmt.Errorf("field myNumber in RequiredFields: required") } - if v, ok := raw["myNumberArray"]; !ok || v == nil { + if _, ok := raw["myNumberArray"]; raw != nil && !ok { return fmt.Errorf("field myNumberArray in RequiredFields: required") } - if v, ok := raw["myObject"]; !ok || v == nil { + if _, ok := raw["myObject"]; raw != nil && !ok { return fmt.Errorf("field myObject in RequiredFields: required") } - if v, ok := raw["myObjectArray"]; !ok || v == nil { + if _, ok := raw["myObjectArray"]; raw != nil && !ok { return fmt.Errorf("field myObjectArray in RequiredFields: required") } - if v, ok := raw["myString"]; !ok || v == nil { + if _, ok := raw["myString"]; raw != nil && !ok { return fmt.Errorf("field myString in RequiredFields: required") } - if v, ok := raw["myStringArray"]; !ok || v == nil { + if _, ok := raw["myStringArray"]; raw != nil && !ok { return fmt.Errorf("field myStringArray in RequiredFields: required") } type Plain RequiredFields diff --git a/tests/data/validation/requiredFields/requiredNullable.go b/tests/data/validation/requiredFields/requiredNullable.go index f82acba1..5c379ba8 100644 --- a/tests/data/validation/requiredFields/requiredNullable.go +++ b/tests/data/validation/requiredFields/requiredNullable.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type RequiredNullable struct { // MyNullableObject corresponds to the JSON schema field "myNullableObject". @@ -23,9 +24,9 @@ type RequiredNullableMyNullableObject struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredNullableMyNullableObject) UnmarshalJSON(b []byte) error { +func (j *RequiredNullableMyNullableObject) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myNestedProp"]; raw != nil && !ok { @@ -33,7 +34,25 @@ func (j *RequiredNullableMyNullableObject) UnmarshalJSON(b []byte) error { } type Plain RequiredNullableMyNullableObject var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = RequiredNullableMyNullableObject(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *RequiredNullableMyNullableObject) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myNestedProp"]; raw != nil && !ok { + return fmt.Errorf("field myNestedProp in RequiredNullableMyNullableObject: required") + } + type Plain RequiredNullableMyNullableObject + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = RequiredNullableMyNullableObject(plain) @@ -41,9 +60,33 @@ func (j *RequiredNullableMyNullableObject) UnmarshalJSON(b []byte) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *RequiredNullable) UnmarshalJSON(b []byte) error { +func (j *RequiredNullable) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if _, ok := raw["myNullableObject"]; raw != nil && !ok { + return fmt.Errorf("field myNullableObject in RequiredNullable: required") + } + if _, ok := raw["myNullableString"]; raw != nil && !ok { + return fmt.Errorf("field myNullableString in RequiredNullable: required") + } + if _, ok := raw["myNullableStringArray"]; raw != nil && !ok { + return fmt.Errorf("field myNullableStringArray in RequiredNullable: required") + } + type Plain RequiredNullable + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = RequiredNullable(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *RequiredNullable) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := value.Decode(&raw); err != nil { return err } if _, ok := raw["myNullableObject"]; raw != nil && !ok { @@ -57,7 +100,7 @@ func (j *RequiredNullable) UnmarshalJSON(b []byte) error { } type Plain RequiredNullable var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } *j = RequiredNullable(plain) diff --git a/tests/generation_test.go b/tests/generation_test.go index 588f47c4..b4f2a6b3 100644 --- a/tests/generation_test.go +++ b/tests/generation_test.go @@ -155,6 +155,12 @@ func TestExtraImportsYAML(t *testing.T) { testExampleFile(t, cfg, "./data/extraImports/gopkgYAMLv3/gopkgYAMLv3.json") } +func TestRegressions(t *testing.T) { + t.Parallel() + + testExamples(t, basicConfig, "./data/regressions") +} + func testExamples(t *testing.T, cfg generator.Config, dataDir string) { t.Helper() @@ -179,12 +185,6 @@ func testExamples(t *testing.T, cfg generator.Config, dataDir string) { } } -func TestRegressions(t *testing.T) { - t.Parallel() - - testExamples(t, basicConfig, "./data/regressions") -} - func TestSchemaExtensions(t *testing.T) { t.Parallel() From deeb799b0b6dd9d2c075a30d51ab6e5d018071a7 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sun, 21 Apr 2024 01:45:02 +0200 Subject: [PATCH 08/16] fix: rename inconsistently-named tests --- .../typed_default.go => typedDefault/typedDefault.go} | 0 .../typed_default.json => typedDefault/typedDefault.json} | 0 .../typedDefaultEmpty.go} | 0 .../typedDefaultEmpty.json} | 0 .../typedDefaultEnums.go} | 0 .../typedDefaultEnums.json} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename tests/data/validation/{typed_default/typed_default.go => typedDefault/typedDefault.go} (100%) rename tests/data/validation/{typed_default/typed_default.json => typedDefault/typedDefault.json} (100%) rename tests/data/validation/{typed_default_empty/typed_default_empty.go => typedDefaultEmpty/typedDefaultEmpty.go} (100%) rename tests/data/validation/{typed_default_empty/typed_default_empty.json => typedDefaultEmpty/typedDefaultEmpty.json} (100%) rename tests/data/validation/{typed_default_enums/typed_default_enums.go => typedDefaultEnums/typedDefaultEnums.go} (100%) rename tests/data/validation/{typed_default_enums/typed_default_enums.json => typedDefaultEnums/typedDefaultEnums.json} (100%) diff --git a/tests/data/validation/typed_default/typed_default.go b/tests/data/validation/typedDefault/typedDefault.go similarity index 100% rename from tests/data/validation/typed_default/typed_default.go rename to tests/data/validation/typedDefault/typedDefault.go diff --git a/tests/data/validation/typed_default/typed_default.json b/tests/data/validation/typedDefault/typedDefault.json similarity index 100% rename from tests/data/validation/typed_default/typed_default.json rename to tests/data/validation/typedDefault/typedDefault.json diff --git a/tests/data/validation/typed_default_empty/typed_default_empty.go b/tests/data/validation/typedDefaultEmpty/typedDefaultEmpty.go similarity index 100% rename from tests/data/validation/typed_default_empty/typed_default_empty.go rename to tests/data/validation/typedDefaultEmpty/typedDefaultEmpty.go diff --git a/tests/data/validation/typed_default_empty/typed_default_empty.json b/tests/data/validation/typedDefaultEmpty/typedDefaultEmpty.json similarity index 100% rename from tests/data/validation/typed_default_empty/typed_default_empty.json rename to tests/data/validation/typedDefaultEmpty/typedDefaultEmpty.json diff --git a/tests/data/validation/typed_default_enums/typed_default_enums.go b/tests/data/validation/typedDefaultEnums/typedDefaultEnums.go similarity index 100% rename from tests/data/validation/typed_default_enums/typed_default_enums.go rename to tests/data/validation/typedDefaultEnums/typedDefaultEnums.go diff --git a/tests/data/validation/typed_default_enums/typed_default_enums.json b/tests/data/validation/typedDefaultEnums/typedDefaultEnums.json similarity index 100% rename from tests/data/validation/typed_default_enums/typed_default_enums.json rename to tests/data/validation/typedDefaultEnums/typedDefaultEnums.json From 66cf1431b054482bce81e754a4575cdd002df60c Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sun, 21 Apr 2024 01:46:39 +0200 Subject: [PATCH 09/16] feat: commit go.work --- .github/workflows/development.yaml | 2 -- .github/workflows/prerelease.yaml | 2 -- .github/workflows/release.yaml | 2 -- .gitignore | 1 - go.work | 6 ++++++ 5 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 go.work diff --git a/.github/workflows/development.yaml b/.github/workflows/development.yaml index f4439cb1..adf04703 100644 --- a/.github/workflows/development.yaml +++ b/.github/workflows/development.yaml @@ -21,8 +21,6 @@ jobs: uses: actions/setup-go@v5 with: go-version: ^1.22.2 - - name: Setup workspace - run: cp go.work.dist go.work - name: Download golangci-lint installer run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh -o /tmp/install-golangci-lint.sh - name: Install golangci-lint diff --git a/.github/workflows/prerelease.yaml b/.github/workflows/prerelease.yaml index 08b595cc..299abe3d 100644 --- a/.github/workflows/prerelease.yaml +++ b/.github/workflows/prerelease.yaml @@ -23,8 +23,6 @@ jobs: uses: actions/setup-go@v5 with: go-version: ^1.22.2 - - name: Setup workspace - run: cp go.work.dist go.work - name: Run GoReleaser for release uses: goreleaser/goreleaser-action@v5 with: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index cbbdf9c9..bb29d052 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -23,8 +23,6 @@ jobs: uses: actions/setup-go@v5 with: go-version: ^1.22.2 - - name: Setup workspace - run: cp go.work.dist go.work - name: Log in to Docker Hub if: ${{ !contains(github.ref_name, '-') }} uses: docker/login-action@v3 diff --git a/.gitignore b/.gitignore index 18774237..bc935297 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,3 @@ coverage/ bin/ dist/ vendor/ -go.work diff --git a/go.work b/go.work new file mode 100644 index 00000000..bd50cfbb --- /dev/null +++ b/go.work @@ -0,0 +1,6 @@ +go 1.22 + +use ( + . + ./tests +) From cef603dc8d7eaa19d198919a68cdaff453298da5 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 26 Oct 2024 15:48:07 +0200 Subject: [PATCH 10/16] chore: update go work --- go.work.sum | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/go.work.sum b/go.work.sum index 5510afad..8eeffa97 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,3 +1,4 @@ +github.com/atombender/go-jsonschema/tests/data v0.0.0-20231003003002-2b73c089a581/go.mod h1:kLoRQLRVy+GT9/PG2e3u31DPvDmtFEn7pX6FItvbqlA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -11,7 +12,6 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -github.com/atombender/go-jsonschema/tests/data v0.0.0-20231003003002-2b73c089a581/go.mod h1:kLoRQLRVy+GT9/PG2e3u31DPvDmtFEn7pX6FItvbqlA= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= @@ -24,8 +24,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -33,5 +33,6 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58 golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From df740dc44ffc46d890d27abc8d7d980caef9fdea Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 16 Nov 2024 15:41:11 +0100 Subject: [PATCH 11/16] chore: align all golang versions to 1.22.9 --- .github/workflows/development.yaml | 4 ++-- .github/workflows/prerelease.yaml | 4 ++-- .github/workflows/release.yaml | 4 ++-- .tool-versions | 2 +- Dockerfile | 2 +- Makefile | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/development.yaml b/.github/workflows/development.yaml index 4f2559b9..7667dd09 100644 --- a/.github/workflows/development.yaml +++ b/.github/workflows/development.yaml @@ -20,7 +20,7 @@ jobs: - name: Setup Golang uses: actions/setup-go@v5 with: - go-version: ^1.22.8 + go-version: ^1.22.9 - name: Setup workspace run: cp go.work.dist go.work - name: Download golangci-lint installer @@ -40,4 +40,4 @@ jobs: version: 2.3.1 args: release --verbose --snapshot --clean env: - GO_VERSION: 1.22.8 + GO_VERSION: 1.22.9 diff --git a/.github/workflows/prerelease.yaml b/.github/workflows/prerelease.yaml index 0cb197b7..213784c6 100644 --- a/.github/workflows/prerelease.yaml +++ b/.github/workflows/prerelease.yaml @@ -22,7 +22,7 @@ jobs: - name: Setup Golang uses: actions/setup-go@v5 with: - go-version: ^1.22.8 + go-version: ^1.22.9 - name: Setup workspace run: cp go.work.dist go.work - name: Run GoReleaser for release @@ -33,4 +33,4 @@ jobs: args: release --verbose --clean env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - GO_VERSION: 1.22.8 + GO_VERSION: 1.22.9 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0e43ff52..2dcff1aa 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -22,7 +22,7 @@ jobs: - name: Setup Golang uses: actions/setup-go@v5 with: - go-version: ^1.22.8 + go-version: ^1.22.9 - name: Setup workspace run: cp go.work.dist go.work - name: Log in to Docker Hub @@ -39,4 +39,4 @@ jobs: args: release --verbose --clean env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - GO_VERSION: 1.22.8 + GO_VERSION: 1.22.9 diff --git a/.tool-versions b/.tool-versions index f9b858de..5937a227 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,5 +1,5 @@ adr-tools 3.0.0 -golang 1.23.3 +golang 1.22.9 golangci-lint 1.62.0 goreleaser 2.3.1 hadolint 2.12.0 diff --git a/Dockerfile b/Dockerfile index ae9351ef..25b8ab84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.23.3-alpine3.20 AS tools +FROM golang:1.22.9-alpine3.20 AS tools COPY scripts/tools-golang.sh /tmp/tools-golang.sh diff --git a/Makefile b/Makefile index 44019f90..6f2e33c9 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ SHELL := /bin/bash # ---------------------------------------------------------------------------------------------------------------------- _DOCKER_FILELINT_IMAGE=cytopia/file-lint:latest-0.8 -_DOCKER_GOLANG_IMAGE=golang:1.22.8 +_DOCKER_GOLANG_IMAGE=golang:1.22.9 _DOCKER_GOLANGCI_LINT_IMAGE=golangci/golangci-lint:v1.61.0 _DOCKER_HADOLINT_IMAGE=hadolint/hadolint:v2.12.0 _DOCKER_JSONLINT_IMAGE=cytopia/jsonlint:1.6 From 0382c50c84732331f2be4bf20551df971580ecbd Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 16 Nov 2024 16:06:48 +0100 Subject: [PATCH 12/16] fix: correct conflict resolution mistakes after updating from main. --- go.mod | 5 --- go.sum | 62 ------------------------------- go.work | 2 +- go.work.sum | 5 ++- pkg/generator/json_formatter.go | 4 +- pkg/generator/schema_generator.go | 14 +++---- pkg/generator/validator.go | 14 +++---- pkg/generator/yaml_formatter.go | 4 +- tests/go.mod | 13 ++----- tests/go.sum | 32 ++-------------- 10 files changed, 30 insertions(+), 125 deletions(-) diff --git a/go.mod b/go.mod index 263678c1..cfcae48f 100644 --- a/go.mod +++ b/go.mod @@ -16,13 +16,8 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.18.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index bcae406c..e30413f8 100644 --- a/go.sum +++ b/go.sum @@ -1,61 +1,15 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b h1:XxMZvQZtTXpWMNWK82vdjCLCe7uGMFXdTsJH0v3Hkvw= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= -github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/goccy/go-yaml v1.13.0 h1:0Wtp0FZLd7Sm8gERmR9S6Iczzb3vItJj7NaHmFg8pTs= -github.com/goccy/go-yaml v1.13.0/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.1 h1:xZqDO9euwefeRx5am/ca9DPSCbV3fMNPkrl+Tivmz8A= -github.com/goccy/go-yaml v1.13.1/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.2 h1:jApcuETDAB6R10spnUfQDTVu090oUwGo+p3GakYTJKw= -github.com/goccy/go-yaml v1.13.2/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.3 h1:IXRULR8mAa0MXQobzzp0VOfMUJ8EnaQ4x3jhf7S0/nI= -github.com/goccy/go-yaml v1.13.3/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.4 h1:XOnLX9GqT+kH/gB7YzCMUiDBFU9B7pm3HZz6kyeDPkk= -github.com/goccy/go-yaml v1.13.4/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.5 h1:/Hh9Q3d1Q2T7E8ECUUS7Uh53FBGKLfetvQoSV7kLViU= -github.com/goccy/go-yaml v1.13.5/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.6 h1:pa3JkBPBseTtfqpG9DiSFhyxNPSpJ0BFa39BlMZE16E= -github.com/goccy/go-yaml v1.13.6/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= -github.com/goccy/go-yaml v1.13.7 h1:5k2i973KptPV1mur30XMXwGepDmskip4gA2zHWzWmOY= -github.com/goccy/go-yaml v1.13.7/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/goccy/go-yaml v1.13.8 h1:ftugzaplJyFaFwfyVNeq1XQOBxmlp8zazmuiobaCXbk= -github.com/goccy/go-yaml v1.13.8/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/goccy/go-yaml v1.13.9 h1:D/LhDa7E5HS/iYxSZzikUSHt1U9q/TeymVBJwodaglc= -github.com/goccy/go-yaml v1.13.9/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/goccy/go-yaml v1.14.0 h1:G/NDXJvf1CX0FshjxKn2AOL0MnrxsSJNpY9FpvMRblw= -github.com/goccy/go-yaml v1.14.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/goccy/go-yaml v1.14.1 h1:NJ9Ch49K/WichY7pAtSvIJbvGjmBDjHVQxuWBbPSOPg= -github.com/goccy/go-yaml v1.14.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/goccy/go-yaml v1.14.2 h1:MzONUP3PM6jnePSNWb2A9fI/xEx1OduPaK/hMC9L9fQ= -github.com/goccy/go-yaml v1.14.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/goccy/go-yaml v1.14.3 h1:8tVD+aqqPLWisSEhM+6wWoiURWXCx6BwaTKS6ZeITgM= github.com/goccy/go-yaml v1.14.3/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -73,24 +27,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw= -golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go.work b/go.work index bd50cfbb..671e7c61 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.22 +go 1.22.0 use ( . diff --git a/go.work.sum b/go.work.sum index d974e26a..537b5e04 100644 --- a/go.work.sum +++ b/go.work.sum @@ -17,6 +17,7 @@ golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= @@ -24,14 +25,15 @@ golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= @@ -50,5 +52,6 @@ golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/generator/json_formatter.go b/pkg/generator/json_formatter.go index 09e07a36..f8f20623 100644 --- a/pkg/generator/json_formatter.go +++ b/pkg/generator/json_formatter.go @@ -46,7 +46,7 @@ func (jf *jsonFormatter) generate( } for _, v := range beforeValidators { - v.generate(out) + v.generate(out, "json") } tp := typePlain @@ -63,7 +63,7 @@ func (jf *jsonFormatter) generate( formatJSON, varNamePlainStruct) for _, v := range afterValidators { - v.generate(out) + v.generate(out, "json") } if structType, ok := declType.Type.(*codegen.StructType); ok { diff --git a/pkg/generator/schema_generator.go b/pkg/generator/schema_generator.go index 03ed676c..c282ae45 100644 --- a/pkg/generator/schema_generator.go +++ b/pkg/generator/schema_generator.go @@ -252,8 +252,8 @@ func (g *schemaGenerator) generateDeclaredType(t *schemas.Type, scope nameScope) var validators []validator - switch theType.(type) { - case codegen.StructType, *codegen.StructType: + switch tt := theType.(type) { + case *codegen.StructType: if t.GetSubSchemaType() == schemas.SubSchemaTypeAnyOf { validators = append(validators, &anyOfValidator{decl.Name, t.GetSubSchemasCount()}) @@ -262,11 +262,11 @@ func (g *schemaGenerator) generateDeclaredType(t *schemas.Type, scope nameScope) return &codegen.NamedType{Decl: &decl}, nil } - for _, f := range structType.RequiredJSONFields { + for _, f := range tt.RequiredJSONFields { validators = append(validators, &requiredValidator{f, decl.Name}) } - for _, f := range structType.Fields { + for _, f := range tt.Fields { if f.DefaultValue != nil { if f.Name == additionalProperties { g.output.file.Package.AddImport("reflect", "") @@ -291,9 +291,9 @@ func (g *schemaGenerator) generateDeclaredType(t *schemas.Type, scope nameScope) case codegen.PrimitiveType, *codegen.PrimitiveType: validators = g.structFieldValidators(nil, codegen.StructField{ - Type: primitiveType, + Type: tt, SchemaType: t, - }, primitiveType, false) + }, tt, false) if t.IsSubSchemaTypeElem() || len(validators) > 0 { g.generateUnmarshaler(decl, validators) @@ -324,7 +324,7 @@ func (g *schemaGenerator) addValidatorsToType(validators []validator, decl codeg formatter.addImport(g.output.file) g.output.file.Package.AddDecl(&codegen.Method{ - Impl: formatter.generate(decl, validators), + Impl: formatter.generate(g.output, decl, validators), Name: decl.GetName() + "_validator", }) } diff --git a/pkg/generator/validator.go b/pkg/generator/validator.go index 42d3e57b..898b1527 100644 --- a/pkg/generator/validator.go +++ b/pkg/generator/validator.go @@ -235,8 +235,8 @@ func (v *arrayValidator) generate(out *codegen.Emitter, format string) { func (v *arrayValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeUnmarshal: false, + hasError: true, + beforeJSONUnmarshal: false, } } @@ -292,8 +292,6 @@ func (v *stringValidator) generate(out *codegen.Emitter, format string) { return } - fieldName := v.jsonName - if v.minLength != 0 { out.Printlnf(`if %slen(%s%s) < %d {`, checkPointer, pointerPrefix, value, v.minLength) out.Indent(1) @@ -313,8 +311,8 @@ func (v *stringValidator) generate(out *codegen.Emitter, format string) { func (v *stringValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeUnmarshal: false, + hasError: true, + beforeJSONUnmarshal: false, } } @@ -448,8 +446,8 @@ func (v *anyOfValidator) generate(out *codegen.Emitter, format string) { func (v *anyOfValidator) desc() *validatorDesc { return &validatorDesc{ - hasError: true, - beforeUnmarshal: true, + hasError: true, + beforeJSONUnmarshal: true, } } diff --git a/pkg/generator/yaml_formatter.go b/pkg/generator/yaml_formatter.go index 6490c292..dae925d6 100644 --- a/pkg/generator/yaml_formatter.go +++ b/pkg/generator/yaml_formatter.go @@ -48,7 +48,7 @@ func (yf *yamlFormatter) generate( } for _, v := range beforeValidators { - v.generate(out) + v.generate(out, "yaml") } tp := typePlain @@ -64,7 +64,7 @@ func (yf *yamlFormatter) generate( out.Printlnf("if err := value.Decode(&%s); err != nil { return err }", varNamePlainStruct) for _, v := range afterValidators { - v.generate(out) + v.generate(out, "yaml") } if structType, ok := declType.Type.(*codegen.StructType); ok { diff --git a/tests/go.mod b/tests/go.mod index ac2cba56..1da53582 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -2,8 +2,6 @@ module github.com/atombender/go-jsonschema/tests go 1.22.0 -toolchain go1.22.0 - replace ( github.com/atombender/go-jsonschema => ../ github.com/atombender/go-jsonschema/tests/helpers/other => ./helpers/other @@ -13,21 +11,18 @@ require ( github.com/atombender/go-jsonschema v0.16.0 github.com/atombender/go-jsonschema/tests/helpers/other v0.0.0-20240909221408-bcba1cdc5eb2 github.com/go-viper/mapstructure/v2 v2.1.0 + github.com/google/go-cmp v0.6.0 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 ) require ( + dario.cat/mergo v1.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.17.0 // indirect - github.com/goccy/go-yaml v1.12.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect + github.com/goccy/go-yaml v1.14.3 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sanity-io/litter v1.5.5 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect ) diff --git a/tests/go.sum b/tests/go.sum index 22c1807b..18cc2899 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -1,30 +1,14 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b h1:XxMZvQZtTXpWMNWK82vdjCLCe7uGMFXdTsJH0v3Hkvw= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= -github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= +github.com/goccy/go-yaml v1.14.3 h1:8tVD+aqqPLWisSEhM+6wWoiURWXCx6BwaTKS6ZeITgM= +github.com/goccy/go-yaml v1.14.3/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -37,16 +21,8 @@ github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= -golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From f5d4790fe724d3e163570934df4d132a3c6a19bc Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 16 Nov 2024 17:38:44 +0100 Subject: [PATCH 13/16] chore: refactor generator code, remove dead code. --- pkg/generator/json_formatter.go | 7 +++---- pkg/generator/schema_generator.go | 23 ----------------------- pkg/generator/yaml_formatter.go | 13 ++++--------- pkg/schemas/model.go | 8 ++++---- pkg/schemas/parse.go | 4 ++-- 5 files changed, 13 insertions(+), 42 deletions(-) diff --git a/pkg/generator/json_formatter.go b/pkg/generator/json_formatter.go index f8f20623..3cdb701b 100644 --- a/pkg/generator/json_formatter.go +++ b/pkg/generator/json_formatter.go @@ -20,7 +20,6 @@ func (jf *jsonFormatter) generate( validators []validator, ) func(*codegen.Emitter) { var beforeValidators []validator - var afterValidators []validator forceBefore := false @@ -42,7 +41,7 @@ func (jf *jsonFormatter) generate( if forceBefore || len(beforeValidators) != 0 { out.Printlnf("var %s map[string]interface{}", varNameRawMap) - out.Printlnf("if err := %s.Unmarshal(b, &%s); err != nil { return err }", formatJSON, varNameRawMap) + out.Printlnf("if err := %s.Unmarshal(value, &%s); err != nil { return err }", formatJSON, varNameRawMap) } for _, v := range beforeValidators { @@ -113,7 +112,7 @@ func (jf *jsonFormatter) enumUnmarshal( ) func(*codegen.Emitter) { return func(out *codegen.Emitter) { out.Comment("UnmarshalJSON implements json.Unmarshaler.") - out.Printlnf("func (j *%s) UnmarshalJSON(b []byte) error {", declType.Name) + out.Printlnf("func (j *%s) UnmarshalJSON(value []byte) error {", declType.Name) out.Indent(1) out.Printf("var v ") enumType.Generate(out) @@ -124,7 +123,7 @@ func (jf *jsonFormatter) enumUnmarshal( varName += ".Value" } - out.Printlnf("if err := json.Unmarshal(b, &%s); err != nil { return err }", varName) + out.Printlnf("if err := json.Unmarshal(value, &%s); err != nil { return err }", varName) out.Printlnf("var ok bool") out.Printlnf("for _, expected := range %s {", valueConstant.Name) out.Printlnf("if reflect.DeepEqual(%s, expected) { ok = true; break }", varName) diff --git a/pkg/generator/schema_generator.go b/pkg/generator/schema_generator.go index c282ae45..9e6caf62 100644 --- a/pkg/generator/schema_generator.go +++ b/pkg/generator/schema_generator.go @@ -305,32 +305,9 @@ func (g *schemaGenerator) generateDeclaredType(t *schemas.Type, scope nameScope) } } - g.addValidatorsToType(validators, decl) - return &codegen.NamedType{Decl: &decl}, nil } -func (g *schemaGenerator) addValidatorsToType(validators []validator, decl codegen.TypeDecl) { - if len(validators) > 0 { - for _, v := range validators { - if v.desc().hasError { - g.output.file.Package.AddImport("fmt", "") - - break - } - } - - for _, formatter := range g.formatters { - formatter.addImport(g.output.file) - - g.output.file.Package.AddDecl(&codegen.Method{ - Impl: formatter.generate(g.output, decl, validators), - Name: decl.GetName() + "_validator", - }) - } - } -} - func (g *schemaGenerator) structFieldValidators( validators []validator, f codegen.StructField, diff --git a/pkg/generator/yaml_formatter.go b/pkg/generator/yaml_formatter.go index dae925d6..6ba88d72 100644 --- a/pkg/generator/yaml_formatter.go +++ b/pkg/generator/yaml_formatter.go @@ -21,7 +21,6 @@ func (yf *yamlFormatter) generate( validators []validator, ) func(*codegen.Emitter) { var beforeValidators []validator - var afterValidators []validator forceBefore := false @@ -38,8 +37,7 @@ func (yf *yamlFormatter) generate( return func(out *codegen.Emitter) { out.Commentf("Unmarshal%s implements %s.Unmarshaler.", strings.ToUpper(formatYAML), formatYAML) - out.Printlnf("func (j *%s) Unmarshal%s(value *yaml.Node) error {", declType.Name, - strings.ToUpper(formatYAML)) + out.Printlnf("func (j *%s) Unmarshal%s(value *yaml.Node) error {", declType.Name, strings.ToUpper(formatYAML)) out.Indent(1) if forceBefore || len(beforeValidators) != 0 { @@ -98,8 +96,7 @@ func (yf *yamlFormatter) generate( func (yf *yamlFormatter) enumMarshal(declType codegen.TypeDecl) func(*codegen.Emitter) { return func(out *codegen.Emitter) { out.Commentf("Marshal%s implements %s.Marshal.", strings.ToUpper(formatYAML), formatYAML) - out.Printlnf("func (j *%s) Marshal%s() (interface{}, error) {", declType.Name, - strings.ToUpper(formatYAML)) + out.Printlnf("func (j *%s) Marshal%s() (interface{}, error) {", declType.Name, strings.ToUpper(formatYAML)) out.Indent(1) out.Printlnf("return %s.Marshal(j.Value)", formatYAML) out.Indent(-1) @@ -115,8 +112,7 @@ func (yf *yamlFormatter) enumUnmarshal( ) func(*codegen.Emitter) { return func(out *codegen.Emitter) { out.Commentf("Unmarshal%s implements %s.Unmarshaler.", strings.ToUpper(formatYAML), formatYAML) - out.Printlnf("func (j *%s) Unmarshal%s(value *yaml.Node) error {", declType.Name, - strings.ToUpper(formatYAML)) + out.Printlnf("func (j *%s) Unmarshal%s(value *yaml.Node) error {", declType.Name, strings.ToUpper(formatYAML)) out.Indent(1) out.Printf("var v ") enumType.Generate(out) @@ -133,8 +129,7 @@ func (yf *yamlFormatter) enumUnmarshal( out.Printlnf("if reflect.DeepEqual(%s, expected) { ok = true; break }", varName) out.Printlnf("}") out.Printlnf("if !ok {") - out.Printlnf(`return fmt.Errorf("invalid value (expected one of %%#v): %%#v", %s, %s)`, - valueConstant.Name, varName) + out.Printlnf(`return fmt.Errorf("invalid value (expected one of %%#v): %%#v", %s, %s)`, valueConstant.Name, varName) out.Printlnf("}") out.Printlnf(`*j = %s(v)`, declType.Name) out.Printlnf(`return nil`) diff --git a/pkg/schemas/model.go b/pkg/schemas/model.go index d6f5af96..ff1add73 100644 --- a/pkg/schemas/model.go +++ b/pkg/schemas/model.go @@ -83,10 +83,10 @@ type ( type TypeList []string // UnmarshalJSON implements json.Unmarshaler. -func (t *TypeList) UnmarshalJSON(b []byte) error { - if len(b) > 0 && b[0] == '[' { +func (t *TypeList) UnmarshalJSON(value []byte) error { + if len(value) > 0 && value[0] == '[' { var s []string - if err := json.Unmarshal(b, &s); err != nil { + if err := json.Unmarshal(value, &s); err != nil { return fmt.Errorf("failed to unmarshal type list: %w", err) } @@ -96,7 +96,7 @@ func (t *TypeList) UnmarshalJSON(b []byte) error { } var s string - if err := json.Unmarshal(b, &s); err != nil { + if err := json.Unmarshal(value, &s); err != nil { return fmt.Errorf("failed to unmarshal type list: %w", err) } diff --git a/pkg/schemas/parse.go b/pkg/schemas/parse.go index a0ceaf8e..ef1970fb 100644 --- a/pkg/schemas/parse.go +++ b/pkg/schemas/parse.go @@ -56,14 +56,14 @@ func FromYAMLReader(r io.Reader) (*Schema, error) { yamlutils.FixMapKeys(m) - b, err := json.Marshal(m) + value, err := json.Marshal(m) if err != nil { return nil, fmt.Errorf("failed to marshal JSON: %w", err) } var schema Schema - if err = json.Unmarshal(b, &schema); err != nil { + if err = json.Unmarshal(value, &schema); err != nil { return nil, fmt.Errorf("failed to unmarshal JSON: %w", err) } From 3a48b717809fa75f0d0b26cb776bb12170458a63 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 16 Nov 2024 17:55:31 +0100 Subject: [PATCH 14/16] fix: regenerate most go-generated code in tests, remove wrong guard in string validator --- pkg/generator/validator.go | 4 - .../arrayAdditionalProperties.go | 10 +- .../boolAdditionalProperties.go | 10 +- .../intAdditionalProperties.go | 10 +- .../numberAdditionalProperties.go | 10 +- .../objectAdditionalProperties.go | 10 +- .../objectWithPropsAdditionalProperties.go | 33 ++- .../stringAdditionalProperties.go | 10 +- tests/data/core/allOf/issue6.go | 4 +- tests/data/core/anyOf/anyOf.go | 8 - .../objectPropertiesDefault.go | 24 +- tests/data/core/refToEnum/refToEnum.go | 4 +- .../extraImports/gopkgYAMLv3/gopkgYAMLv3.go | 4 +- .../gopkgYAMLv3AdditionalProperties.go | 6 +- tests/data/minSizedInts/arrays/exact.go | 46 +++- .../minSizedInts/exactReferences/exact.go | 46 +++- tests/data/minSizedInts/exactSizes/exact.go | 46 +++- .../exactSizesExclusiveBool/exact.go | 46 +++- .../exactSizesExclusiveNum/exact.go | 46 +++- tests/data/minSizedInts/largerSizes/larger.go | 76 +++++- .../restrictedSizes/restricted.go | 85 ++++++- .../restrictedSizesReferences/restricted.go | 229 ++++++++++++++++-- .../specialCharacters/specialCharacters.go | 32 +-- tests/data/validation/enum/enum.go | 44 ++-- .../exclusiveMaximum/exclusiveMaximum.go | 40 ++- .../exclusiveMaximum/exclusiveMaximumOld.go | 37 ++- .../exclusiveMinimum/exclusiveMinimum.go | 40 ++- .../exclusiveMinimum/exclusiveMinimumOld.go | 37 ++- tests/data/validation/maxItems/maxItems.go | 8 - tests/data/validation/maximum/maximum.go | 40 ++- tests/data/validation/minItems/minItems.go | 8 - .../validation/minMaxItems/minMaxItems.go | 8 - tests/data/validation/minimum/minimum.go | 40 ++- .../data/validation/multipleOf/multipleOf.go | 40 ++- tests/data/validation/pattern/pattern.go | 33 ++- .../primitive_defs/primitive_defs.go | 43 +++- .../typedDefaultEnums/typedDefaultEnums.go | 4 +- 37 files changed, 1036 insertions(+), 185 deletions(-) diff --git a/pkg/generator/validator.go b/pkg/generator/validator.go index 898b1527..b792e004 100644 --- a/pkg/generator/validator.go +++ b/pkg/generator/validator.go @@ -250,10 +250,6 @@ type stringValidator struct { } func (v *stringValidator) generate(out *codegen.Emitter, format string) { - if v.minLength == 0 && v.maxLength == 0 { - return - } - value := getPlainName(v.fieldName) fieldName := v.jsonName checkPointer := "" diff --git a/tests/data/core/additionalProperties/arrayAdditionalProperties.go b/tests/data/core/additionalProperties/arrayAdditionalProperties.go index e1be05ff..ccf03a42 100644 --- a/tests/data/core/additionalProperties/arrayAdditionalProperties.go +++ b/tests/data/core/additionalProperties/arrayAdditionalProperties.go @@ -3,8 +3,8 @@ package test import "encoding/json" -import yaml "gopkg.in/yaml.v3" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -29,6 +29,14 @@ func (j *ArrayAdditionalProperties) UnmarshalJSON(value []byte) error { if v, ok := raw[""]; !ok || v == nil { plain.AdditionalProperties = map[string][]interface{}{} } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } *j = ArrayAdditionalProperties(plain) return nil } diff --git a/tests/data/core/additionalProperties/boolAdditionalProperties.go b/tests/data/core/additionalProperties/boolAdditionalProperties.go index 0272fed1..aff4c336 100644 --- a/tests/data/core/additionalProperties/boolAdditionalProperties.go +++ b/tests/data/core/additionalProperties/boolAdditionalProperties.go @@ -3,8 +3,8 @@ package test import "encoding/json" -import yaml "gopkg.in/yaml.v3" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -29,6 +29,14 @@ func (j *BoolAdditionalProperties) UnmarshalJSON(value []byte) error { if v, ok := raw[""]; !ok || v == nil { plain.AdditionalProperties = map[string]bool{} } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } *j = BoolAdditionalProperties(plain) return nil } diff --git a/tests/data/core/additionalProperties/intAdditionalProperties.go b/tests/data/core/additionalProperties/intAdditionalProperties.go index 9ca6cb57..fd669321 100644 --- a/tests/data/core/additionalProperties/intAdditionalProperties.go +++ b/tests/data/core/additionalProperties/intAdditionalProperties.go @@ -3,8 +3,8 @@ package test import "encoding/json" -import yaml "gopkg.in/yaml.v3" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -29,6 +29,14 @@ func (j *IntAdditionalProperties) UnmarshalJSON(value []byte) error { if v, ok := raw[""]; !ok || v == nil { plain.AdditionalProperties = map[string]int{} } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } *j = IntAdditionalProperties(plain) return nil } diff --git a/tests/data/core/additionalProperties/numberAdditionalProperties.go b/tests/data/core/additionalProperties/numberAdditionalProperties.go index 3720bf38..0933d5f1 100644 --- a/tests/data/core/additionalProperties/numberAdditionalProperties.go +++ b/tests/data/core/additionalProperties/numberAdditionalProperties.go @@ -3,8 +3,8 @@ package test import "encoding/json" -import yaml "gopkg.in/yaml.v3" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -29,6 +29,14 @@ func (j *NumberAdditionalProperties) UnmarshalJSON(value []byte) error { if v, ok := raw[""]; !ok || v == nil { plain.AdditionalProperties = map[string]float64{} } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } *j = NumberAdditionalProperties(plain) return nil } diff --git a/tests/data/core/additionalProperties/objectAdditionalProperties.go b/tests/data/core/additionalProperties/objectAdditionalProperties.go index 6ffa12ae..a8e6d074 100644 --- a/tests/data/core/additionalProperties/objectAdditionalProperties.go +++ b/tests/data/core/additionalProperties/objectAdditionalProperties.go @@ -3,8 +3,8 @@ package test import "encoding/json" -import yaml "gopkg.in/yaml.v3" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -29,6 +29,14 @@ func (j *ObjectAdditionalProperties) UnmarshalJSON(value []byte) error { if v, ok := raw[""]; !ok || v == nil { plain.AdditionalProperties = map[string]interface{}{} } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } *j = ObjectAdditionalProperties(plain) return nil } diff --git a/tests/data/core/additionalProperties/objectWithPropsAdditionalProperties.go b/tests/data/core/additionalProperties/objectWithPropsAdditionalProperties.go index d27efcd3..631cab31 100644 --- a/tests/data/core/additionalProperties/objectWithPropsAdditionalProperties.go +++ b/tests/data/core/additionalProperties/objectWithPropsAdditionalProperties.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -18,14 +19,40 @@ type ObjectWithPropsAdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ObjectWithPropsAdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *ObjectWithPropsAdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain ObjectWithPropsAdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if v, ok := raw[""]; !ok || v == nil { + plain.AdditionalProperties = map[string]interface{}{} + } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } + *j = ObjectWithPropsAdditionalProperties(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ObjectWithPropsAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + type Plain ObjectWithPropsAdditionalProperties + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/core/additionalProperties/stringAdditionalProperties.go b/tests/data/core/additionalProperties/stringAdditionalProperties.go index b4448e24..783ef7a2 100644 --- a/tests/data/core/additionalProperties/stringAdditionalProperties.go +++ b/tests/data/core/additionalProperties/stringAdditionalProperties.go @@ -3,8 +3,8 @@ package test import "encoding/json" -import yaml "gopkg.in/yaml.v3" import "github.com/go-viper/mapstructure/v2" +import yaml "gopkg.in/yaml.v3" import "reflect" import "strings" @@ -29,6 +29,14 @@ func (j *StringAdditionalProperties) UnmarshalJSON(value []byte) error { if v, ok := raw[""]; !ok || v == nil { plain.AdditionalProperties = map[string]string{} } + st := reflect.TypeOf(Plain{}) + for i := range st.NumField() { + delete(raw, st.Field(i).Name) + delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) + } + if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { + return err + } *j = StringAdditionalProperties(plain) return nil } diff --git a/tests/data/core/allOf/issue6.go b/tests/data/core/allOf/issue6.go index 90005a11..705f214a 100644 --- a/tests/data/core/allOf/issue6.go +++ b/tests/data/core/allOf/issue6.go @@ -103,9 +103,9 @@ func (j *Issue6NameUse_2) UnmarshalYAML(value *yaml.Node) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Issue6NameUse_2) UnmarshalJSON(b []byte) error { +func (j *Issue6NameUse_2) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool diff --git a/tests/data/core/anyOf/anyOf.go b/tests/data/core/anyOf/anyOf.go index 8ee46c8a..bfcedb61 100644 --- a/tests/data/core/anyOf/anyOf.go +++ b/tests/data/core/anyOf/anyOf.go @@ -115,10 +115,6 @@ type AnyOfConfigurationsElem_2 struct { // UnmarshalJSON implements json.Unmarshaler. func (j *AnyOfConfigurationsElem_2) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } type Plain AnyOfConfigurationsElem_2 var plain Plain if err := json.Unmarshal(value, &plain); err != nil { @@ -130,10 +126,6 @@ func (j *AnyOfConfigurationsElem_2) UnmarshalJSON(value []byte) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *AnyOfConfigurationsElem_2) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } type Plain AnyOfConfigurationsElem_2 var plain Plain if err := value.Decode(&plain); err != nil { diff --git a/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go index 81a1ec68..057b5c42 100644 --- a/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go +++ b/tests/data/core/objectPropertiesDefault/objectPropertiesDefault.go @@ -128,9 +128,9 @@ var enumValues_EventName = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EventName) UnmarshalJSON(b []byte) error { +func (j *EventName) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -202,9 +202,9 @@ func (j *EventTagsElem) UnmarshalYAML(value *yaml.Node) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *EventTagsElem) UnmarshalJSON(b []byte) error { +func (j *EventTagsElem) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -280,10 +280,6 @@ type ObjectPropertiesDefaultPlannersElem_0 struct { // UnmarshalYAML implements yaml.Unmarshaler. func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } type Plain ObjectPropertiesDefaultPlannersElem_0 var plain Plain if err := value.Decode(&plain); err != nil { @@ -295,10 +291,6 @@ func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalYAML(value *yaml.Node) // UnmarshalJSON implements json.Unmarshaler. func (j *ObjectPropertiesDefaultPlannersElem_0) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } type Plain ObjectPropertiesDefaultPlannersElem_0 var plain Plain if err := json.Unmarshal(value, &plain); err != nil { @@ -315,10 +307,6 @@ type ObjectPropertiesDefaultPlannersElem_1 struct { // UnmarshalJSON implements json.Unmarshaler. func (j *ObjectPropertiesDefaultPlannersElem_1) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } type Plain ObjectPropertiesDefaultPlannersElem_1 var plain Plain if err := json.Unmarshal(value, &plain); err != nil { @@ -330,10 +318,6 @@ func (j *ObjectPropertiesDefaultPlannersElem_1) UnmarshalJSON(value []byte) erro // UnmarshalYAML implements yaml.Unmarshaler. func (j *ObjectPropertiesDefaultPlannersElem_1) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } type Plain ObjectPropertiesDefaultPlannersElem_1 var plain Plain if err := value.Decode(&plain); err != nil { diff --git a/tests/data/core/refToEnum/refToEnum.go b/tests/data/core/refToEnum/refToEnum.go index 22bb84c3..66e192c5 100644 --- a/tests/data/core/refToEnum/refToEnum.go +++ b/tests/data/core/refToEnum/refToEnum.go @@ -23,9 +23,9 @@ var enumValues_Thing = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *Thing) UnmarshalJSON(b []byte) error { +func (j *Thing) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool diff --git a/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go b/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go index 895ba3a0..5b9409d1 100644 --- a/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go +++ b/tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.go @@ -38,9 +38,9 @@ var enumValues_GopkgYAMLv3MyEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *GopkgYAMLv3MyEnum) UnmarshalJSON(b []byte) error { +func (j *GopkgYAMLv3MyEnum) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool diff --git a/tests/data/extraImports/gopkgYAMLv3AdditionalProperties/gopkgYAMLv3AdditionalProperties.go b/tests/data/extraImports/gopkgYAMLv3AdditionalProperties/gopkgYAMLv3AdditionalProperties.go index c4a44ac2..75c94468 100644 --- a/tests/data/extraImports/gopkgYAMLv3AdditionalProperties/gopkgYAMLv3AdditionalProperties.go +++ b/tests/data/extraImports/gopkgYAMLv3AdditionalProperties/gopkgYAMLv3AdditionalProperties.go @@ -19,14 +19,14 @@ type GopkgYAMLv3AdditionalProperties struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *GopkgYAMLv3AdditionalProperties) UnmarshalJSON(b []byte) error { +func (j *GopkgYAMLv3AdditionalProperties) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } type Plain GopkgYAMLv3AdditionalProperties var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } if v, ok := raw[""]; !ok || v == nil { diff --git a/tests/data/minSizedInts/arrays/exact.go b/tests/data/minSizedInts/arrays/exact.go index 6d2b5144..43a772ec 100644 --- a/tests/data/minSizedInts/arrays/exact.go +++ b/tests/data/minSizedInts/arrays/exact.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Exact struct { // I16 corresponds to the JSON schema field "i16". @@ -32,9 +33,9 @@ type Exact struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Exact) UnmarshalJSON(b []byte) error { +func (j *Exact) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16"]; raw != nil && !ok { @@ -63,7 +64,46 @@ func (j *Exact) UnmarshalJSON(b []byte) error { } type Plain Exact var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = Exact(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Exact) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16"]; raw != nil && !ok { + return fmt.Errorf("field i16 in Exact: required") + } + if _, ok := raw["i32"]; raw != nil && !ok { + return fmt.Errorf("field i32 in Exact: required") + } + if _, ok := raw["i64"]; raw != nil && !ok { + return fmt.Errorf("field i64 in Exact: required") + } + if _, ok := raw["i8"]; raw != nil && !ok { + return fmt.Errorf("field i8 in Exact: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Exact: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Exact: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Exact: required") + } + if _, ok := raw["u8"]; raw != nil && !ok { + return fmt.Errorf("field u8 in Exact: required") + } + type Plain Exact + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = Exact(plain) diff --git a/tests/data/minSizedInts/exactReferences/exact.go b/tests/data/minSizedInts/exactReferences/exact.go index 9626254b..186a0cf5 100644 --- a/tests/data/minSizedInts/exactReferences/exact.go +++ b/tests/data/minSizedInts/exactReferences/exact.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Bound16 int16 @@ -40,9 +41,9 @@ type Exact struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Exact) UnmarshalJSON(b []byte) error { +func (j *Exact) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16"]; raw != nil && !ok { @@ -71,7 +72,46 @@ func (j *Exact) UnmarshalJSON(b []byte) error { } type Plain Exact var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = Exact(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Exact) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16"]; raw != nil && !ok { + return fmt.Errorf("field i16 in Exact: required") + } + if _, ok := raw["i32"]; raw != nil && !ok { + return fmt.Errorf("field i32 in Exact: required") + } + if _, ok := raw["i64"]; raw != nil && !ok { + return fmt.Errorf("field i64 in Exact: required") + } + if _, ok := raw["i8"]; raw != nil && !ok { + return fmt.Errorf("field i8 in Exact: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Exact: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Exact: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Exact: required") + } + if _, ok := raw["u8"]; raw != nil && !ok { + return fmt.Errorf("field u8 in Exact: required") + } + type Plain Exact + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = Exact(plain) diff --git a/tests/data/minSizedInts/exactSizes/exact.go b/tests/data/minSizedInts/exactSizes/exact.go index 766343b4..d545ade0 100644 --- a/tests/data/minSizedInts/exactSizes/exact.go +++ b/tests/data/minSizedInts/exactSizes/exact.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Exact struct { // I16 corresponds to the JSON schema field "i16". @@ -32,9 +33,9 @@ type Exact struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Exact) UnmarshalJSON(b []byte) error { +func (j *Exact) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16"]; raw != nil && !ok { @@ -63,7 +64,46 @@ func (j *Exact) UnmarshalJSON(b []byte) error { } type Plain Exact var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = Exact(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Exact) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16"]; raw != nil && !ok { + return fmt.Errorf("field i16 in Exact: required") + } + if _, ok := raw["i32"]; raw != nil && !ok { + return fmt.Errorf("field i32 in Exact: required") + } + if _, ok := raw["i64"]; raw != nil && !ok { + return fmt.Errorf("field i64 in Exact: required") + } + if _, ok := raw["i8"]; raw != nil && !ok { + return fmt.Errorf("field i8 in Exact: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Exact: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Exact: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Exact: required") + } + if _, ok := raw["u8"]; raw != nil && !ok { + return fmt.Errorf("field u8 in Exact: required") + } + type Plain Exact + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = Exact(plain) diff --git a/tests/data/minSizedInts/exactSizesExclusiveBool/exact.go b/tests/data/minSizedInts/exactSizesExclusiveBool/exact.go index 766343b4..d545ade0 100644 --- a/tests/data/minSizedInts/exactSizesExclusiveBool/exact.go +++ b/tests/data/minSizedInts/exactSizesExclusiveBool/exact.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Exact struct { // I16 corresponds to the JSON schema field "i16". @@ -32,9 +33,9 @@ type Exact struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Exact) UnmarshalJSON(b []byte) error { +func (j *Exact) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16"]; raw != nil && !ok { @@ -63,7 +64,46 @@ func (j *Exact) UnmarshalJSON(b []byte) error { } type Plain Exact var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = Exact(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Exact) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16"]; raw != nil && !ok { + return fmt.Errorf("field i16 in Exact: required") + } + if _, ok := raw["i32"]; raw != nil && !ok { + return fmt.Errorf("field i32 in Exact: required") + } + if _, ok := raw["i64"]; raw != nil && !ok { + return fmt.Errorf("field i64 in Exact: required") + } + if _, ok := raw["i8"]; raw != nil && !ok { + return fmt.Errorf("field i8 in Exact: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Exact: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Exact: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Exact: required") + } + if _, ok := raw["u8"]; raw != nil && !ok { + return fmt.Errorf("field u8 in Exact: required") + } + type Plain Exact + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = Exact(plain) diff --git a/tests/data/minSizedInts/exactSizesExclusiveNum/exact.go b/tests/data/minSizedInts/exactSizesExclusiveNum/exact.go index 766343b4..d545ade0 100644 --- a/tests/data/minSizedInts/exactSizesExclusiveNum/exact.go +++ b/tests/data/minSizedInts/exactSizesExclusiveNum/exact.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Exact struct { // I16 corresponds to the JSON schema field "i16". @@ -32,9 +33,9 @@ type Exact struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Exact) UnmarshalJSON(b []byte) error { +func (j *Exact) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16"]; raw != nil && !ok { @@ -63,7 +64,46 @@ func (j *Exact) UnmarshalJSON(b []byte) error { } type Plain Exact var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = Exact(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Exact) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16"]; raw != nil && !ok { + return fmt.Errorf("field i16 in Exact: required") + } + if _, ok := raw["i32"]; raw != nil && !ok { + return fmt.Errorf("field i32 in Exact: required") + } + if _, ok := raw["i64"]; raw != nil && !ok { + return fmt.Errorf("field i64 in Exact: required") + } + if _, ok := raw["i8"]; raw != nil && !ok { + return fmt.Errorf("field i8 in Exact: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Exact: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Exact: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Exact: required") + } + if _, ok := raw["u8"]; raw != nil && !ok { + return fmt.Errorf("field u8 in Exact: required") + } + type Plain Exact + var plain Plain + if err := value.Decode(&plain); err != nil { return err } *j = Exact(plain) diff --git a/tests/data/minSizedInts/largerSizes/larger.go b/tests/data/minSizedInts/largerSizes/larger.go index 2622581e..db91def2 100644 --- a/tests/data/minSizedInts/largerSizes/larger.go +++ b/tests/data/minSizedInts/largerSizes/larger.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Larger struct { // I16L corresponds to the JSON schema field "i16l". @@ -35,9 +36,9 @@ type Larger struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Larger) UnmarshalJSON(b []byte) error { +func (j *Larger) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["u16"]; raw != nil && !ok { @@ -51,7 +52,76 @@ func (j *Larger) UnmarshalJSON(b []byte) error { } type Plain Larger var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.I16L != nil && 127 < *plain.I16L { + return fmt.Errorf("field %s: must be <= %v", "i16l", 127) + } + if plain.I16L != nil && -129 > *plain.I16L { + return fmt.Errorf("field %s: must be >= %v", "i16l", -129) + } + if plain.I16U != nil && 128 < *plain.I16U { + return fmt.Errorf("field %s: must be <= %v", "i16u", 128) + } + if plain.I16U != nil && -128 > *plain.I16U { + return fmt.Errorf("field %s: must be >= %v", "i16u", -128) + } + if plain.I32L != nil && 32767 < *plain.I32L { + return fmt.Errorf("field %s: must be <= %v", "i32l", 32767) + } + if plain.I32L != nil && -32769 > *plain.I32L { + return fmt.Errorf("field %s: must be >= %v", "i32l", -32769) + } + if plain.I32U != nil && 32768 < *plain.I32U { + return fmt.Errorf("field %s: must be <= %v", "i32u", 32768) + } + if plain.I32U != nil && -32768 > *plain.I32U { + return fmt.Errorf("field %s: must be >= %v", "i32u", -32768) + } + if plain.I64L != nil && 2147483647 < *plain.I64L { + return fmt.Errorf("field %s: must be <= %v", "i64l", 2147483647) + } + if plain.I64L != nil && -2147483649 > *plain.I64L { + return fmt.Errorf("field %s: must be >= %v", "i64l", -2147483649) + } + if plain.I64U != nil && 2147483648 < *plain.I64U { + return fmt.Errorf("field %s: must be <= %v", "i64u", 2147483648) + } + if plain.I64U != nil && -2147483648 > *plain.I64U { + return fmt.Errorf("field %s: must be >= %v", "i64u", -2147483648) + } + if 256 < plain.U16 { + return fmt.Errorf("field %s: must be <= %v", "u16", 256) + } + if 65536 < plain.U32 { + return fmt.Errorf("field %s: must be <= %v", "u32", 65536) + } + if 4294967296 < plain.U64 { + return fmt.Errorf("field %s: must be <= %v", "u64", 4294967296) + } + *j = Larger(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Larger) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Larger: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Larger: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Larger: required") + } + type Plain Larger + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.I16L != nil && 127 < *plain.I16L { diff --git a/tests/data/minSizedInts/restrictedSizes/restricted.go b/tests/data/minSizedInts/restrictedSizes/restricted.go index 700a3f93..d8b716d6 100644 --- a/tests/data/minSizedInts/restrictedSizes/restricted.go +++ b/tests/data/minSizedInts/restrictedSizes/restricted.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Restricted struct { // I16 corresponds to the JSON schema field "i16". @@ -32,9 +33,9 @@ type Restricted struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Restricted) UnmarshalJSON(b []byte) error { +func (j *Restricted) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16"]; raw != nil && !ok { @@ -63,7 +64,85 @@ func (j *Restricted) UnmarshalJSON(b []byte) error { } type Plain Restricted var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 32766 < plain.I16 { + return fmt.Errorf("field %s: must be <= %v", "i16", 32766) + } + if -32767 > plain.I16 { + return fmt.Errorf("field %s: must be >= %v", "i16", -32767) + } + if 2147483646 < plain.I32 { + return fmt.Errorf("field %s: must be <= %v", "i32", 2147483646) + } + if -2147483647 > plain.I32 { + return fmt.Errorf("field %s: must be >= %v", "i32", -2147483647) + } + if 126 < plain.I8 { + return fmt.Errorf("field %s: must be <= %v", "i8", 126) + } + if -127 > plain.I8 { + return fmt.Errorf("field %s: must be >= %v", "i8", -127) + } + if 65534 < plain.U16 { + return fmt.Errorf("field %s: must be <= %v", "u16", 65534) + } + if 1 > plain.U16 { + return fmt.Errorf("field %s: must be >= %v", "u16", 1) + } + if 4294967294 < plain.U32 { + return fmt.Errorf("field %s: must be <= %v", "u32", 4294967294) + } + if 1 > plain.U32 { + return fmt.Errorf("field %s: must be >= %v", "u32", 1) + } + if 1 > plain.U64 { + return fmt.Errorf("field %s: must be >= %v", "u64", 1) + } + if 254 < plain.U8 { + return fmt.Errorf("field %s: must be <= %v", "u8", 254) + } + if 1 > plain.U8 { + return fmt.Errorf("field %s: must be >= %v", "u8", 1) + } + *j = Restricted(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Restricted) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16"]; raw != nil && !ok { + return fmt.Errorf("field i16 in Restricted: required") + } + if _, ok := raw["i32"]; raw != nil && !ok { + return fmt.Errorf("field i32 in Restricted: required") + } + if _, ok := raw["i64"]; raw != nil && !ok { + return fmt.Errorf("field i64 in Restricted: required") + } + if _, ok := raw["i8"]; raw != nil && !ok { + return fmt.Errorf("field i8 in Restricted: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Restricted: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Restricted: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Restricted: required") + } + if _, ok := raw["u8"]; raw != nil && !ok { + return fmt.Errorf("field u8 in Restricted: required") + } + type Plain Restricted + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 32766 < plain.I16 { diff --git a/tests/data/minSizedInts/restrictedSizesReferences/restricted.go b/tests/data/minSizedInts/restrictedSizesReferences/restricted.go index 5c94b2a7..d5ddd192 100644 --- a/tests/data/minSizedInts/restrictedSizesReferences/restricted.go +++ b/tests/data/minSizedInts/restrictedSizesReferences/restricted.go @@ -4,14 +4,32 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type I16L int16 // UnmarshalJSON implements json.Unmarshaler. -func (j *I16L) UnmarshalJSON(b []byte) error { +func (j *I16L) UnmarshalJSON(value []byte) error { type Plain I16L var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 127 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 127) + } + if -129 > plain { + return fmt.Errorf("field %s: must be >= %v", "", -129) + } + *j = I16L(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *I16L) UnmarshalYAML(value *yaml.Node) error { + type Plain I16L + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 127 < plain { @@ -27,10 +45,27 @@ func (j *I16L) UnmarshalJSON(b []byte) error { type I16U int16 // UnmarshalJSON implements json.Unmarshaler. -func (j *I16U) UnmarshalJSON(b []byte) error { +func (j *I16U) UnmarshalJSON(value []byte) error { type Plain I16U var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 128 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 128) + } + if -128 > plain { + return fmt.Errorf("field %s: must be >= %v", "", -128) + } + *j = I16U(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *I16U) UnmarshalYAML(value *yaml.Node) error { + type Plain I16U + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 128 < plain { @@ -46,10 +81,27 @@ func (j *I16U) UnmarshalJSON(b []byte) error { type I32L int32 // UnmarshalJSON implements json.Unmarshaler. -func (j *I32L) UnmarshalJSON(b []byte) error { +func (j *I32L) UnmarshalJSON(value []byte) error { + type Plain I32L + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 32767 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 32767) + } + if -32769 > plain { + return fmt.Errorf("field %s: must be >= %v", "", -32769) + } + *j = I32L(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *I32L) UnmarshalYAML(value *yaml.Node) error { type Plain I32L var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } if 32767 < plain { @@ -65,10 +117,27 @@ func (j *I32L) UnmarshalJSON(b []byte) error { type I32U int32 // UnmarshalJSON implements json.Unmarshaler. -func (j *I32U) UnmarshalJSON(b []byte) error { +func (j *I32U) UnmarshalJSON(value []byte) error { + type Plain I32U + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 32768 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 32768) + } + if -32768 > plain { + return fmt.Errorf("field %s: must be >= %v", "", -32768) + } + *j = I32U(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *I32U) UnmarshalYAML(value *yaml.Node) error { type Plain I32U var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } if 32768 < plain { @@ -83,11 +152,28 @@ func (j *I32U) UnmarshalJSON(b []byte) error { type I64L int64 +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *I64L) UnmarshalYAML(value *yaml.Node) error { + type Plain I64L + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if 2147483647 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 2147483647) + } + if -2147483649 > plain { + return fmt.Errorf("field %s: must be >= %v", "", -2147483649) + } + *j = I64L(plain) + return nil +} + // UnmarshalJSON implements json.Unmarshaler. -func (j *I64L) UnmarshalJSON(b []byte) error { +func (j *I64L) UnmarshalJSON(value []byte) error { type Plain I64L var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } if 2147483647 < plain { @@ -103,10 +189,27 @@ func (j *I64L) UnmarshalJSON(b []byte) error { type I64U int64 // UnmarshalJSON implements json.Unmarshaler. -func (j *I64U) UnmarshalJSON(b []byte) error { +func (j *I64U) UnmarshalJSON(value []byte) error { type Plain I64U var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2147483648 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 2147483648) + } + if -2147483648 > plain { + return fmt.Errorf("field %s: must be >= %v", "", -2147483648) + } + *j = I64U(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *I64U) UnmarshalYAML(value *yaml.Node) error { + type Plain I64U + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2147483648 < plain { @@ -148,10 +251,52 @@ type Restricted struct { U64 U64 `json:"u64" yaml:"u64" mapstructure:"u64"` } +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Restricted) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["i16l"]; raw != nil && !ok { + return fmt.Errorf("field i16l in Restricted: required") + } + if _, ok := raw["i16u"]; raw != nil && !ok { + return fmt.Errorf("field i16u in Restricted: required") + } + if _, ok := raw["i32l"]; raw != nil && !ok { + return fmt.Errorf("field i32l in Restricted: required") + } + if _, ok := raw["i32u"]; raw != nil && !ok { + return fmt.Errorf("field i32u in Restricted: required") + } + if _, ok := raw["i64l"]; raw != nil && !ok { + return fmt.Errorf("field i64l in Restricted: required") + } + if _, ok := raw["i64u"]; raw != nil && !ok { + return fmt.Errorf("field i64u in Restricted: required") + } + if _, ok := raw["u16"]; raw != nil && !ok { + return fmt.Errorf("field u16 in Restricted: required") + } + if _, ok := raw["u32"]; raw != nil && !ok { + return fmt.Errorf("field u32 in Restricted: required") + } + if _, ok := raw["u64"]; raw != nil && !ok { + return fmt.Errorf("field u64 in Restricted: required") + } + type Plain Restricted + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + *j = Restricted(plain) + return nil +} + // UnmarshalJSON implements json.Unmarshaler. -func (j *Restricted) UnmarshalJSON(b []byte) error { +func (j *Restricted) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["i16l"]; raw != nil && !ok { @@ -183,7 +328,7 @@ func (j *Restricted) UnmarshalJSON(b []byte) error { } type Plain Restricted var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } *j = Restricted(plain) @@ -193,10 +338,24 @@ func (j *Restricted) UnmarshalJSON(b []byte) error { type U16 uint16 // UnmarshalJSON implements json.Unmarshaler. -func (j *U16) UnmarshalJSON(b []byte) error { +func (j *U16) UnmarshalJSON(value []byte) error { type Plain U16 var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 256 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 256) + } + *j = U16(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *U16) UnmarshalYAML(value *yaml.Node) error { + type Plain U16 + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 256 < plain { @@ -209,10 +368,24 @@ func (j *U16) UnmarshalJSON(b []byte) error { type U32 uint32 // UnmarshalJSON implements json.Unmarshaler. -func (j *U32) UnmarshalJSON(b []byte) error { +func (j *U32) UnmarshalJSON(value []byte) error { + type Plain U32 + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 65536 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 65536) + } + *j = U32(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *U32) UnmarshalYAML(value *yaml.Node) error { type Plain U32 var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } if 65536 < plain { @@ -224,11 +397,25 @@ func (j *U32) UnmarshalJSON(b []byte) error { type U64 uint64 +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *U64) UnmarshalYAML(value *yaml.Node) error { + type Plain U64 + var plain Plain + if err := value.Decode(&plain); err != nil { + return err + } + if 4294967296 < plain { + return fmt.Errorf("field %s: must be <= %v", "", 4294967296) + } + *j = U64(plain) + return nil +} + // UnmarshalJSON implements json.Unmarshaler. -func (j *U64) UnmarshalJSON(b []byte) error { +func (j *U64) UnmarshalJSON(value []byte) error { type Plain U64 var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { return err } if 4294967296 < plain { diff --git a/tests/data/misc/specialCharacters/specialCharacters.go b/tests/data/misc/specialCharacters/specialCharacters.go index 959995de..345d787d 100644 --- a/tests/data/misc/specialCharacters/specialCharacters.go +++ b/tests/data/misc/specialCharacters/specialCharacters.go @@ -25,10 +25,10 @@ var enumValues_License_1 = []interface{}{ "*", } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *License_1) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *License_1) UnmarshalJSON(value []byte) error { var v string - if err := value.Decode(&v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -45,10 +45,10 @@ func (j *License_1) UnmarshalYAML(value *yaml.Node) error { return nil } -// UnmarshalJSON implements json.Unmarshaler. -func (j *License_1) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *License_1) UnmarshalYAML(value *yaml.Node) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := value.Decode(&v); err != nil { return err } var ok bool @@ -92,9 +92,9 @@ func (j *License) UnmarshalYAML(value *yaml.Node) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *License) UnmarshalJSON(b []byte) error { +func (j *License) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -138,9 +138,9 @@ var enumValues_SpecialCharactersPlainLicenses = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *SpecialCharactersPlainLicenses) UnmarshalJSON(b []byte) error { +func (j *SpecialCharactersPlainLicenses) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -189,10 +189,10 @@ var enumValues_SpecialCharactersPlusLicenses = []interface{}{ "*", } -// UnmarshalJSON implements json.Unmarshaler. -func (j *SpecialCharactersPlusLicenses) UnmarshalJSON(b []byte) error { +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *SpecialCharactersPlusLicenses) UnmarshalYAML(value *yaml.Node) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := value.Decode(&v); err != nil { return err } var ok bool @@ -209,10 +209,10 @@ func (j *SpecialCharactersPlusLicenses) UnmarshalJSON(b []byte) error { return nil } -// UnmarshalYAML implements yaml.Unmarshaler. -func (j *SpecialCharactersPlusLicenses) UnmarshalYAML(value *yaml.Node) error { +// UnmarshalJSON implements json.Unmarshaler. +func (j *SpecialCharactersPlusLicenses) UnmarshalJSON(value []byte) error { var v string - if err := value.Decode(&v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool diff --git a/tests/data/validation/enum/enum.go b/tests/data/validation/enum/enum.go index ec2f692d..8092a449 100644 --- a/tests/data/validation/enum/enum.go +++ b/tests/data/validation/enum/enum.go @@ -51,9 +51,9 @@ var enumValues_EnumMyBooleanTypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyBooleanTypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyBooleanTypedEnum) UnmarshalJSON(value []byte) error { var v bool - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -98,9 +98,9 @@ var enumValues_EnumMyBooleanUntypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyBooleanUntypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyBooleanUntypedEnum) UnmarshalJSON(value []byte) error { var v bool - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -146,9 +146,9 @@ var enumValues_EnumMyIntegerTypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyIntegerTypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyIntegerTypedEnum) UnmarshalJSON(value []byte) error { var v int - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -227,11 +227,11 @@ func (j *EnumMyMixedTypeEnum) UnmarshalYAML(value *yaml.Node) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyMixedTypeEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyMixedTypeEnum) UnmarshalJSON(value []byte) error { var v struct { Value interface{} } - if err := json.Unmarshal(b, &v.Value); err != nil { + if err := json.Unmarshal(value, &v.Value); err != nil { return err } var ok bool @@ -270,11 +270,11 @@ var enumValues_EnumMyMixedUntypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyMixedUntypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyMixedUntypedEnum) UnmarshalJSON(value []byte) error { var v struct { Value interface{} } - if err := json.Unmarshal(b, &v.Value); err != nil { + if err := json.Unmarshal(value, &v.Value); err != nil { return err } var ok bool @@ -332,11 +332,11 @@ var enumValues_EnumMyNullTypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyNullTypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyNullTypedEnum) UnmarshalJSON(value []byte) error { var v struct { Value interface{} } - if err := json.Unmarshal(b, &v.Value); err != nil { + if err := json.Unmarshal(value, &v.Value); err != nil { return err } var ok bool @@ -394,11 +394,11 @@ var enumValues_EnumMyNullUntypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyNullUntypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyNullUntypedEnum) UnmarshalJSON(value []byte) error { var v struct { Value interface{} } - if err := json.Unmarshal(b, &v.Value); err != nil { + if err := json.Unmarshal(value, &v.Value); err != nil { return err } var ok bool @@ -446,9 +446,9 @@ var enumValues_EnumMyNumberTypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyNumberTypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyNumberTypedEnum) UnmarshalJSON(value []byte) error { var v float64 - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -494,9 +494,9 @@ var enumValues_EnumMyNumberUntypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyNumberUntypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyNumberUntypedEnum) UnmarshalJSON(value []byte) error { var v float64 - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -546,9 +546,9 @@ var enumValues_EnumMyStringTypedEnum = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyStringTypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyStringTypedEnum) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool @@ -618,9 +618,9 @@ func (j *EnumMyStringUntypedEnum) UnmarshalYAML(value *yaml.Node) error { } // UnmarshalJSON implements json.Unmarshaler. -func (j *EnumMyStringUntypedEnum) UnmarshalJSON(b []byte) error { +func (j *EnumMyStringUntypedEnum) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool diff --git a/tests/data/validation/exclusiveMaximum/exclusiveMaximum.go b/tests/data/validation/exclusiveMaximum/exclusiveMaximum.go index 63058c63..97c275a1 100644 --- a/tests/data/validation/exclusiveMaximum/exclusiveMaximum.go +++ b/tests/data/validation/exclusiveMaximum/exclusiveMaximum.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type ExclusiveMaximum struct { // MyInteger corresponds to the JSON schema field "myInteger". @@ -20,9 +21,9 @@ type ExclusiveMaximum struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ExclusiveMaximum) UnmarshalJSON(b []byte) error { +func (j *ExclusiveMaximum) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -33,7 +34,40 @@ func (j *ExclusiveMaximum) UnmarshalJSON(b []byte) error { } type Plain ExclusiveMaximum var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2 <= plain.MyInteger { + return fmt.Errorf("field %s: must be < %v", "myInteger", 2) + } + if plain.MyNullableInteger != nil && 2 <= *plain.MyNullableInteger { + return fmt.Errorf("field %s: must be < %v", "myNullableInteger", 2) + } + if plain.MyNullableNumber != nil && 1.2 <= *plain.MyNullableNumber { + return fmt.Errorf("field %s: must be < %v", "myNullableNumber", 1.2) + } + if 1.2 <= plain.MyNumber { + return fmt.Errorf("field %s: must be < %v", "myNumber", 1.2) + } + *j = ExclusiveMaximum(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ExclusiveMaximum) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in ExclusiveMaximum: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in ExclusiveMaximum: required") + } + type Plain ExclusiveMaximum + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2 <= plain.MyInteger { diff --git a/tests/data/validation/exclusiveMaximum/exclusiveMaximumOld.go b/tests/data/validation/exclusiveMaximum/exclusiveMaximumOld.go index d5ea57d3..8b4baaaa 100644 --- a/tests/data/validation/exclusiveMaximum/exclusiveMaximumOld.go +++ b/tests/data/validation/exclusiveMaximum/exclusiveMaximumOld.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type ExclusiveMaximumOld struct { // MyInteger corresponds to the JSON schema field "myInteger". @@ -20,9 +21,9 @@ type ExclusiveMaximumOld struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ExclusiveMaximumOld) UnmarshalJSON(b []byte) error { +func (j *ExclusiveMaximumOld) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -33,7 +34,37 @@ func (j *ExclusiveMaximumOld) UnmarshalJSON(b []byte) error { } type Plain ExclusiveMaximumOld var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2 <= plain.MyInteger { + return fmt.Errorf("field %s: must be < %v", "myInteger", 2) + } + if plain.MyNullableInteger != nil && 2 <= *plain.MyNullableInteger { + return fmt.Errorf("field %s: must be < %v", "myNullableInteger", 2) + } + if 1.2 <= plain.MyNumber { + return fmt.Errorf("field %s: must be < %v", "myNumber", 1.2) + } + *j = ExclusiveMaximumOld(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ExclusiveMaximumOld) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in ExclusiveMaximumOld: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in ExclusiveMaximumOld: required") + } + type Plain ExclusiveMaximumOld + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2 <= plain.MyInteger { diff --git a/tests/data/validation/exclusiveMinimum/exclusiveMinimum.go b/tests/data/validation/exclusiveMinimum/exclusiveMinimum.go index a405360e..c198e8fc 100644 --- a/tests/data/validation/exclusiveMinimum/exclusiveMinimum.go +++ b/tests/data/validation/exclusiveMinimum/exclusiveMinimum.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type ExclusiveMinimum struct { // MyInteger corresponds to the JSON schema field "myInteger". @@ -20,9 +21,9 @@ type ExclusiveMinimum struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ExclusiveMinimum) UnmarshalJSON(b []byte) error { +func (j *ExclusiveMinimum) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -33,7 +34,40 @@ func (j *ExclusiveMinimum) UnmarshalJSON(b []byte) error { } type Plain ExclusiveMinimum var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2 >= plain.MyInteger { + return fmt.Errorf("field %s: must be > %v", "myInteger", 2) + } + if plain.MyNullableInteger != nil && 2 >= *plain.MyNullableInteger { + return fmt.Errorf("field %s: must be > %v", "myNullableInteger", 2) + } + if plain.MyNullableNumber != nil && 1.2 >= *plain.MyNullableNumber { + return fmt.Errorf("field %s: must be > %v", "myNullableNumber", 1.2) + } + if 1.2 >= plain.MyNumber { + return fmt.Errorf("field %s: must be > %v", "myNumber", 1.2) + } + *j = ExclusiveMinimum(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ExclusiveMinimum) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in ExclusiveMinimum: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in ExclusiveMinimum: required") + } + type Plain ExclusiveMinimum + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2 >= plain.MyInteger { diff --git a/tests/data/validation/exclusiveMinimum/exclusiveMinimumOld.go b/tests/data/validation/exclusiveMinimum/exclusiveMinimumOld.go index 7f58e500..b5e37927 100644 --- a/tests/data/validation/exclusiveMinimum/exclusiveMinimumOld.go +++ b/tests/data/validation/exclusiveMinimum/exclusiveMinimumOld.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type ExclusiveMinimumOld struct { // MyInteger corresponds to the JSON schema field "myInteger". @@ -20,9 +21,9 @@ type ExclusiveMinimumOld struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *ExclusiveMinimumOld) UnmarshalJSON(b []byte) error { +func (j *ExclusiveMinimumOld) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -33,7 +34,37 @@ func (j *ExclusiveMinimumOld) UnmarshalJSON(b []byte) error { } type Plain ExclusiveMinimumOld var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2 >= plain.MyInteger { + return fmt.Errorf("field %s: must be > %v", "myInteger", 2) + } + if plain.MyNullableInteger != nil && 2 >= *plain.MyNullableInteger { + return fmt.Errorf("field %s: must be > %v", "myNullableInteger", 2) + } + if 1.2 >= plain.MyNumber { + return fmt.Errorf("field %s: must be > %v", "myNumber", 1.2) + } + *j = ExclusiveMinimumOld(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *ExclusiveMinimumOld) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in ExclusiveMinimumOld: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in ExclusiveMinimumOld: required") + } + type Plain ExclusiveMinimumOld + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2 >= plain.MyInteger { diff --git a/tests/data/validation/maxItems/maxItems.go b/tests/data/validation/maxItems/maxItems.go index fbe7a99e..8e7738f1 100644 --- a/tests/data/validation/maxItems/maxItems.go +++ b/tests/data/validation/maxItems/maxItems.go @@ -16,10 +16,6 @@ type MaxItems struct { // UnmarshalJSON implements json.Unmarshaler. func (j *MaxItems) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } type Plain MaxItems var plain Plain if err := json.Unmarshal(value, &plain); err != nil { @@ -42,10 +38,6 @@ func (j *MaxItems) UnmarshalJSON(value []byte) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *MaxItems) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } type Plain MaxItems var plain Plain if err := value.Decode(&plain); err != nil { diff --git a/tests/data/validation/maximum/maximum.go b/tests/data/validation/maximum/maximum.go index 5bcebdb5..02b525fc 100644 --- a/tests/data/validation/maximum/maximum.go +++ b/tests/data/validation/maximum/maximum.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Maximum struct { // MyInteger corresponds to the JSON schema field "myInteger". @@ -20,9 +21,9 @@ type Maximum struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Maximum) UnmarshalJSON(b []byte) error { +func (j *Maximum) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -33,7 +34,40 @@ func (j *Maximum) UnmarshalJSON(b []byte) error { } type Plain Maximum var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2 < plain.MyInteger { + return fmt.Errorf("field %s: must be <= %v", "myInteger", 2) + } + if plain.MyNullableInteger != nil && 2 < *plain.MyNullableInteger { + return fmt.Errorf("field %s: must be <= %v", "myNullableInteger", 2) + } + if plain.MyNullableNumber != nil && 1.2 < *plain.MyNullableNumber { + return fmt.Errorf("field %s: must be <= %v", "myNullableNumber", 1.2) + } + if 1.2 < plain.MyNumber { + return fmt.Errorf("field %s: must be <= %v", "myNumber", 1.2) + } + *j = Maximum(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Maximum) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in Maximum: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in Maximum: required") + } + type Plain Maximum + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2 < plain.MyInteger { diff --git a/tests/data/validation/minItems/minItems.go b/tests/data/validation/minItems/minItems.go index 050b2594..b532e98d 100644 --- a/tests/data/validation/minItems/minItems.go +++ b/tests/data/validation/minItems/minItems.go @@ -16,10 +16,6 @@ type MinItems struct { // UnmarshalJSON implements json.Unmarshaler. func (j *MinItems) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } type Plain MinItems var plain Plain if err := json.Unmarshal(value, &plain); err != nil { @@ -42,10 +38,6 @@ func (j *MinItems) UnmarshalJSON(value []byte) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *MinItems) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } type Plain MinItems var plain Plain if err := value.Decode(&plain); err != nil { diff --git a/tests/data/validation/minMaxItems/minMaxItems.go b/tests/data/validation/minMaxItems/minMaxItems.go index 1d338c8f..7ce25063 100644 --- a/tests/data/validation/minMaxItems/minMaxItems.go +++ b/tests/data/validation/minMaxItems/minMaxItems.go @@ -16,10 +16,6 @@ type MinMaxItems struct { // UnmarshalJSON implements json.Unmarshaler. func (j *MinMaxItems) UnmarshalJSON(value []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(value, &raw); err != nil { - return err - } type Plain MinMaxItems var plain Plain if err := json.Unmarshal(value, &plain); err != nil { @@ -51,10 +47,6 @@ func (j *MinMaxItems) UnmarshalJSON(value []byte) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *MinMaxItems) UnmarshalYAML(value *yaml.Node) error { - var raw map[string]interface{} - if err := value.Decode(&raw); err != nil { - return err - } type Plain MinMaxItems var plain Plain if err := value.Decode(&plain); err != nil { diff --git a/tests/data/validation/minimum/minimum.go b/tests/data/validation/minimum/minimum.go index 9f561a2a..ae7957b7 100644 --- a/tests/data/validation/minimum/minimum.go +++ b/tests/data/validation/minimum/minimum.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type Minimum struct { // MyInteger corresponds to the JSON schema field "myInteger". @@ -20,9 +21,9 @@ type Minimum struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Minimum) UnmarshalJSON(b []byte) error { +func (j *Minimum) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -33,7 +34,40 @@ func (j *Minimum) UnmarshalJSON(b []byte) error { } type Plain Minimum var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if 2 > plain.MyInteger { + return fmt.Errorf("field %s: must be >= %v", "myInteger", 2) + } + if plain.MyNullableInteger != nil && 2 > *plain.MyNullableInteger { + return fmt.Errorf("field %s: must be >= %v", "myNullableInteger", 2) + } + if plain.MyNullableNumber != nil && 1.2 > *plain.MyNullableNumber { + return fmt.Errorf("field %s: must be >= %v", "myNullableNumber", 1.2) + } + if 1.2 > plain.MyNumber { + return fmt.Errorf("field %s: must be >= %v", "myNumber", 1.2) + } + *j = Minimum(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Minimum) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in Minimum: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in Minimum: required") + } + type Plain Minimum + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if 2 > plain.MyInteger { diff --git a/tests/data/validation/multipleOf/multipleOf.go b/tests/data/validation/multipleOf/multipleOf.go index d611316b..4d8af7ae 100644 --- a/tests/data/validation/multipleOf/multipleOf.go +++ b/tests/data/validation/multipleOf/multipleOf.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "math" type MultipleOf struct { @@ -21,9 +22,9 @@ type MultipleOf struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *MultipleOf) UnmarshalJSON(b []byte) error { +func (j *MultipleOf) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myInteger"]; raw != nil && !ok { @@ -34,7 +35,40 @@ func (j *MultipleOf) UnmarshalJSON(b []byte) error { } type Plain MultipleOf var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyInteger%2 != 0 { + return fmt.Errorf("field %s: must be a multiple of %v", "myInteger", 2.000000) + } + if plain.MyNullableInteger != nil && *plain.MyNullableInteger%2 != 0 { + return fmt.Errorf("field %s: must be a multiple of %v", "myNullableInteger", 2.000000) + } + if plain.MyNullableNumber != nil && math.Abs(math.Mod(*plain.MyNullableNumber, 1.2)) > 1e-10 { + return fmt.Errorf("field %s: must be a multiple of %v", "myNullableNumber", 1.200000) + } + if math.Abs(math.Mod(plain.MyNumber, 1.2)) > 1e-10 { + return fmt.Errorf("field %s: must be a multiple of %v", "myNumber", 1.200000) + } + *j = MultipleOf(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MultipleOf) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myInteger"]; raw != nil && !ok { + return fmt.Errorf("field myInteger in MultipleOf: required") + } + if _, ok := raw["myNumber"]; raw != nil && !ok { + return fmt.Errorf("field myNumber in MultipleOf: required") + } + type Plain MultipleOf + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyInteger%2 != 0 { diff --git a/tests/data/validation/pattern/pattern.go b/tests/data/validation/pattern/pattern.go index f3ab50d7..bd72c9d9 100644 --- a/tests/data/validation/pattern/pattern.go +++ b/tests/data/validation/pattern/pattern.go @@ -4,6 +4,7 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" import "regexp" type Pattern struct { @@ -15,9 +16,9 @@ type Pattern struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *Pattern) UnmarshalJSON(b []byte) error { +func (j *Pattern) UnmarshalJSON(value []byte) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := json.Unmarshal(value, &raw); err != nil { return err } if _, ok := raw["myString"]; raw != nil && !ok { @@ -25,7 +26,33 @@ func (j *Pattern) UnmarshalJSON(b []byte) error { } type Plain Pattern var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if plain.MyNullableString != nil { + if matched, _ := regexp.MatchString(`^0x[0-9a-f]{10}$`, string(*plain.MyNullableString)); !matched { + return fmt.Errorf("field %s pattern match: must match %s", `^0x[0-9a-f]{10}$`, "MyNullableString") + } + } + if matched, _ := regexp.MatchString(`^0x[0-9a-f]{10}\.$`, string(plain.MyString)); !matched { + return fmt.Errorf("field %s pattern match: must match %s", `^0x[0-9a-f]{10}\.$`, "MyString") + } + *j = Pattern(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *Pattern) UnmarshalYAML(value *yaml.Node) error { + var raw map[string]interface{} + if err := value.Decode(&raw); err != nil { + return err + } + if _, ok := raw["myString"]; raw != nil && !ok { + return fmt.Errorf("field myString in Pattern: required") + } + type Plain Pattern + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if plain.MyNullableString != nil { diff --git a/tests/data/validation/primitive_defs/primitive_defs.go b/tests/data/validation/primitive_defs/primitive_defs.go index 48c2bac1..f28d8bdc 100644 --- a/tests/data/validation/primitive_defs/primitive_defs.go +++ b/tests/data/validation/primitive_defs/primitive_defs.go @@ -4,14 +4,29 @@ package test import "encoding/json" import "fmt" +import yaml "gopkg.in/yaml.v3" type MinStr string // UnmarshalJSON implements json.Unmarshaler. -func (j *MinStr) UnmarshalJSON(b []byte) error { +func (j *MinStr) UnmarshalJSON(value []byte) error { type Plain MinStr var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + if len(plain) < 5 { + return fmt.Errorf("field %s length: must be >= %d", "", 5) + } + *j = MinStr(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *MinStr) UnmarshalYAML(value *yaml.Node) error { + type Plain MinStr + var plain Plain + if err := value.Decode(&plain); err != nil { return err } if len(plain) < 5 { @@ -30,9 +45,27 @@ type PrimitiveDefs struct { } // UnmarshalJSON implements json.Unmarshaler. -func (j *PrimitiveDefs) UnmarshalJSON(b []byte) error { +func (j *PrimitiveDefs) UnmarshalJSON(value []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(value, &raw); err != nil { + return err + } + if _, ok := raw["myString"]; raw != nil && !ok { + return fmt.Errorf("field myString in PrimitiveDefs: required") + } + type Plain PrimitiveDefs + var plain Plain + if err := json.Unmarshal(value, &plain); err != nil { + return err + } + *j = PrimitiveDefs(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *PrimitiveDefs) UnmarshalYAML(value *yaml.Node) error { var raw map[string]interface{} - if err := json.Unmarshal(b, &raw); err != nil { + if err := value.Decode(&raw); err != nil { return err } if _, ok := raw["myString"]; raw != nil && !ok { @@ -40,7 +73,7 @@ func (j *PrimitiveDefs) UnmarshalJSON(b []byte) error { } type Plain PrimitiveDefs var plain Plain - if err := json.Unmarshal(b, &plain); err != nil { + if err := value.Decode(&plain); err != nil { return err } *j = PrimitiveDefs(plain) diff --git a/tests/data/validation/typedDefaultEnums/typedDefaultEnums.go b/tests/data/validation/typedDefaultEnums/typedDefaultEnums.go index 4d4f01d9..932cc292 100644 --- a/tests/data/validation/typedDefaultEnums/typedDefaultEnums.go +++ b/tests/data/validation/typedDefaultEnums/typedDefaultEnums.go @@ -23,9 +23,9 @@ var enumValues_TypedDefaultEnumsSome = []interface{}{ } // UnmarshalJSON implements json.Unmarshaler. -func (j *TypedDefaultEnumsSome) UnmarshalJSON(b []byte) error { +func (j *TypedDefaultEnumsSome) UnmarshalJSON(value []byte) error { var v string - if err := json.Unmarshal(b, &v); err != nil { + if err := json.Unmarshal(value, &v); err != nil { return err } var ok bool From d5c4ac82a9b705cfbe33846b09d433f3e6107994 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 16 Nov 2024 17:55:42 +0100 Subject: [PATCH 15/16] chore: remove useless file --- tests/data/crossPackageNoOutput/other/other.go | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 tests/data/crossPackageNoOutput/other/other.go diff --git a/tests/data/crossPackageNoOutput/other/other.go b/tests/data/crossPackageNoOutput/other/other.go deleted file mode 100644 index 46f7e8ad..00000000 --- a/tests/data/crossPackageNoOutput/other/other.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. - -package test - -type Thing struct { - // S corresponds to the JSON schema field "s". - S *string `json:"s,omitempty" yaml:"s,omitempty" mapstructure:"s,omitempty"` -} From 6e36da2c6458ce8ba88933c655db21dbf69516f2 Mon Sep 17 00:00:00 2001 From: Claudio Beatrice Date: Sat, 16 Nov 2024 18:02:34 +0100 Subject: [PATCH 16/16] fix: address linting issues. --- .rules/.golangci.yml | 1 + pkg/generator/json_formatter.go | 6 ++++-- pkg/generator/schema_generator.go | 2 +- pkg/generator/yaml_formatter.go | 6 ++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.rules/.golangci.yml b/.rules/.golangci.yml index e55c8a96..756d23a0 100644 --- a/.rules/.golangci.yml +++ b/.rules/.golangci.yml @@ -40,6 +40,7 @@ linters: - exhaustruct - forbidigo - gomnd + - mnd linters-settings: decorder: diff --git a/pkg/generator/json_formatter.go b/pkg/generator/json_formatter.go index 3cdb701b..8e249015 100644 --- a/pkg/generator/json_formatter.go +++ b/pkg/generator/json_formatter.go @@ -19,8 +19,10 @@ func (jf *jsonFormatter) generate( declType codegen.TypeDecl, validators []validator, ) func(*codegen.Emitter) { - var beforeValidators []validator - var afterValidators []validator + var ( + beforeValidators []validator + afterValidators []validator + ) forceBefore := false diff --git a/pkg/generator/schema_generator.go b/pkg/generator/schema_generator.go index 9e6caf62..c042f96c 100644 --- a/pkg/generator/schema_generator.go +++ b/pkg/generator/schema_generator.go @@ -793,7 +793,7 @@ func (g *schemaGenerator) generateTypeInline(t *schemas.Type, scope nameScope) ( if schemas.IsPrimitiveType(t.Type[typeIndex]) { if t.IsSubSchemaTypeElem() { - return nil, nil + return nil, nil //nolint: nilnil // TODO: this should be fixed, but it requires a refactor. } cg, err := codegen.PrimitiveTypeFromJSONSchemaType( diff --git a/pkg/generator/yaml_formatter.go b/pkg/generator/yaml_formatter.go index 6ba88d72..c6f24281 100644 --- a/pkg/generator/yaml_formatter.go +++ b/pkg/generator/yaml_formatter.go @@ -20,8 +20,10 @@ func (yf *yamlFormatter) generate( declType codegen.TypeDecl, validators []validator, ) func(*codegen.Emitter) { - var beforeValidators []validator - var afterValidators []validator + var ( + beforeValidators []validator + afterValidators []validator + ) forceBefore := false