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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions gen/schema_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ func (g *schemaGen) generate(name string, schema *jsonschema.Schema, optional bo
}()

schema = transformSchema(schema)
schema, err := flattenAllOfSchema(schema)
if err != nil {
return nil, errors.Wrap(err, "flatten allOf")
}

t, err := g.generate2(name, schema)
if err != nil {
Expand Down
71 changes: 53 additions & 18 deletions gen/schema_gen_sum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1203,27 +1203,11 @@ func (g *schemaGen) oneOf(name string, schema *jsonschema.Schema, side bool) (*i
}

func (g *schemaGen) allOf(name string, schema *jsonschema.Schema) (*ir.Type, error) {
if err := ensureNoInfiniteRecursion(schema); err != nil {
return nil, err
}

// If there is only one schema in allOf, avoid merging to keep the reference.
if len(schema.AllOf) == 1 {
s := schema.AllOf[0]
if s != nil {
return g.generate(name, s, false)
}
}

mergedSchema, err := mergeNSchemes(schema.AllOf)
mergedSchema, err := flattenAllOfSchema(schema)
if err != nil {
return nil, err
}

// The reference field must not change
mergedSchema.Ref = schema.Ref

return g.generate(name, mergedSchema, false)
return g.generate2(name, mergedSchema)
}

// shallowSchemaCopy returns a shallow copy of the given schema.
Expand All @@ -1239,6 +1223,57 @@ func shallowSchemaCopy(s *jsonschema.Schema) *jsonschema.Schema {
return &cpy
}

func flattenAllOfSchema(schema *jsonschema.Schema) (*jsonschema.Schema, error) {
if schema == nil || len(schema.AllOf) == 0 {
return schema, nil
}

if err := ensureNoInfiniteRecursion(schema); err != nil {
return nil, err
}

parent := shallowSchemaCopy(schema)
parent.AllOf = nil

// If there is only one schema in allOf, avoid merging and keep the inner schema
// while still applying wrapper-level metadata from the parent.
if len(schema.AllOf) == 1 {
child := shallowSchemaCopy(schema.AllOf[0])
if child == nil {
return parent, nil
}

child.Nullable = child.Nullable || parent.Nullable
if child.Type == jsonschema.Empty {
child.Type = parent.Type
}
if child.Ref.IsZero() {
child.Ref = parent.Ref
}
if _, ok := child.Position(); !ok {
child.Pointer = parent.Pointer
}
return child, nil
}

mergedSchema, err := mergeNSchemes(schema.AllOf)
if err != nil {
return nil, err
}

mergedSchema.Nullable = mergedSchema.Nullable || parent.Nullable
if mergedSchema.Type == jsonschema.Empty {
mergedSchema.Type = parent.Type
}
// The reference field must not change.
mergedSchema.Ref = parent.Ref
if _, ok := mergedSchema.Position(); !ok {
mergedSchema.Pointer = parent.Pointer
}

return mergedSchema, nil
}

func mergeNSchemes(ss []*jsonschema.Schema) (_ *jsonschema.Schema, err error) {
switch len(ss) {
case 0:
Expand Down
27 changes: 27 additions & 0 deletions gen/schema_transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,33 @@ func TestNullableOneOf_Optionality(t *testing.T) {
assertOptionalNullableGeneric(t, optionalField.Type, ir.KindPrimitive)
})

t.Run("optional nullable allOf field", func(t *testing.T) {
a := require.New(t)
s := createTestSchemaGen(nil)

nullableStringAllOf := &jsonschema.Schema{
AllOf: []*jsonschema.Schema{
createPrimitiveSchema(jsonschema.String),
{Nullable: true},
},
}

optionalSchema := createObjectSchema(
createProperty("optionalNullable", nullableStringAllOf, false),
)
optionalResult, err := s.generate("WithOptionalAllOf", optionalSchema, false)

a.NoError(err)
a.NotNil(optionalResult)
a.Equal(ir.KindStruct, optionalResult.Kind)
a.Len(optionalResult.Fields, 1)

optionalField := optionalResult.Fields[0]
a.Equal("OptionalNullable", optionalField.Name)
assertOptionalNullableGeneric(t, optionalField.Type, ir.KindPrimitive)
a.Equal(ir.String, optionalField.Type.GenericOf.Primitive)
})

t.Run("field in optional object", func(t *testing.T) {
a := require.New(t)
s := createTestSchemaGen(nil)
Expand Down
7 changes: 7 additions & 0 deletions json/mac.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package json

import (
"net"
"strings"

"github.com/go-faster/errors"
"github.com/go-faster/jx"
)

Expand All @@ -12,6 +14,11 @@ func DecodeMAC(d *jx.Decoder) (net.HardwareAddr, error) {
if err != nil {
return nil, err
}
// Keep behavior stable across Go versions by requiring an explicit
// MAC separator.
if !strings.ContainsAny(raw, ":-.") {
return nil, errors.New("invalid MAC address format")
}
return net.ParseMAC(raw)
}

Expand Down
Loading