Skip to content

Commit 9c9cee2

Browse files
committed
feat: improve support for accessing additional properties in go models
1 parent 89ebaf4 commit 9c9cee2

15 files changed

+311
-36
lines changed

pkg/generator/schema_generator.go

+68-13
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package generator
22

33
import (
4+
"errors"
45
"fmt"
56
"strings"
67

78
"github.com/atombender/go-jsonschema/pkg/codegen"
89
"github.com/atombender/go-jsonschema/pkg/schemas"
910
)
1011

12+
var errTooManyTypesForAdditionalProperties = errors.New("cannot support multiple types for additional properties")
13+
1114
type schemaGenerator struct {
1215
*Generator
1316
output *output
@@ -339,7 +342,8 @@ func (g *schemaGenerator) structFieldValidators(
339342
}
340343

341344
func (g *schemaGenerator) generateType(
342-
t *schemas.Type, scope nameScope,
345+
t *schemas.Type,
346+
scope nameScope,
343347
) (codegen.Type, error) {
344348
typeIndex := 0
345349

@@ -531,20 +535,71 @@ func (g *schemaGenerator) generateStructType(
531535
structType.AddField(structField)
532536
}
533537

538+
// Checking .Not here because `false` is unmarshalled to .Not = Type{}.
534539
if t.AdditionalProperties != nil && t.AdditionalProperties.Not == nil {
535-
// checking .Not here because `false` is unmarshalled to .Not = Type{}
536-
if valueType, err := g.generateType(t.AdditionalProperties, nil); err != nil {
537-
return nil, err
538-
} else {
539-
structType.AddField(
540-
codegen.StructField{
541-
Name: "AdditionalProperties",
542-
DefaultValue: map[string]interface{}{},
543-
SchemaType: &schemas.Type{},
544-
Type: valueType,
545-
},
546-
)
540+
if len(t.AdditionalProperties.Type) > 1 {
541+
return nil, errTooManyTypesForAdditionalProperties
542+
}
543+
544+
var (
545+
defaultValue any = nil
546+
fieldType codegen.Type = codegen.EmptyInterfaceType{}
547+
)
548+
549+
if len(t.AdditionalProperties.Type) == 1 {
550+
switch t.AdditionalProperties.Type[0] {
551+
case schemas.TypeNameString:
552+
defaultValue = map[string]string{}
553+
fieldType = codegen.MapType{
554+
KeyType: codegen.PrimitiveType{Type: "string"},
555+
ValueType: codegen.PrimitiveType{Type: "string"},
556+
}
557+
558+
case schemas.TypeNameArray:
559+
defaultValue = map[string][]any{}
560+
fieldType = codegen.MapType{
561+
KeyType: codegen.PrimitiveType{Type: "string"},
562+
ValueType: codegen.ArrayType{Type: codegen.EmptyInterfaceType{}},
563+
}
564+
565+
case schemas.TypeNameNumber:
566+
defaultValue = map[string]float64{}
567+
fieldType = codegen.MapType{
568+
KeyType: codegen.PrimitiveType{Type: "string"},
569+
ValueType: codegen.PrimitiveType{Type: "float64"},
570+
}
571+
572+
case schemas.TypeNameInteger:
573+
defaultValue = map[string]int{}
574+
fieldType = codegen.MapType{
575+
KeyType: codegen.PrimitiveType{Type: "string"},
576+
ValueType: codegen.PrimitiveType{Type: "int"},
577+
}
578+
579+
case schemas.TypeNameBoolean:
580+
defaultValue = map[string]bool{}
581+
fieldType = codegen.MapType{
582+
KeyType: codegen.PrimitiveType{Type: "string"},
583+
ValueType: codegen.PrimitiveType{Type: "bool"},
584+
}
585+
586+
default:
587+
defaultValue = map[string]any{}
588+
fieldType = codegen.MapType{
589+
KeyType: codegen.PrimitiveType{Type: "string"},
590+
ValueType: codegen.EmptyInterfaceType{},
591+
}
592+
}
547593
}
594+
595+
structType.AddField(
596+
codegen.StructField{
597+
Name: "AdditionalProperties",
598+
DefaultValue: defaultValue,
599+
SchemaType: &schemas.Type{},
600+
Type: fieldType,
601+
},
602+
)
548603
}
549604

550605
return &structType, nil

tests/data/core/additionalProperties/arrayAdditionalProperties.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"name": {
6+
"type": "string"
7+
}
8+
},
9+
"additionalProperties": {"type": "array"}
10+
}

tests/data/core/additionalProperties/boolAdditionalProperties.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"name": {
6+
"type": "string"
7+
}
8+
},
9+
"additionalProperties": {"type": "boolean"}
10+
}

tests/data/core/additionalProperties/intAdditionalProperties.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"name": {
6+
"type": "string"
7+
}
8+
},
9+
"additionalProperties": {"type": "integer"}
10+
}

tests/data/core/additionalProperties/numberAdditionalProperties.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"name": {
6+
"type": "string"
7+
}
8+
},
9+
"additionalProperties": {"type": "number"}
10+
}

tests/data/core/additionalProperties/objectAdditionalProperties.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"name": {
6+
"type": "string"
7+
}
8+
},
9+
"additionalProperties": {"type": "object"}
10+
}

tests/data/core/additionalProperties/stringAdditionalProperties.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"name": {
6+
"type": "string"
7+
}
8+
},
9+
"additionalProperties": {"type": "string"}
10+
}

tests/data/regressions/issue51/issue51.go

+2-22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)