Skip to content

Commit

Permalink
feat: improve support for accessing additional properties in go models
Browse files Browse the repository at this point in the history
  • Loading branch information
omissis committed Apr 20, 2024
1 parent 2d0ec25 commit 0b49bf8
Show file tree
Hide file tree
Showing 15 changed files with 311 additions and 36 deletions.
81 changes: 68 additions & 13 deletions pkg/generator/schema_generator.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package generator

import (
"errors"
"fmt"
"strings"

"github.com/atombender/go-jsonschema/pkg/codegen"
"github.com/atombender/go-jsonschema/pkg/schemas"
)

var errTooManyTypesForAdditionalProperties = errors.New("cannot support multiple types for additional properties")

type schemaGenerator struct {
*Generator
output *output
Expand Down Expand Up @@ -339,7 +342,8 @@ func (g *schemaGenerator) structFieldValidators(
}

func (g *schemaGenerator) generateType(
t *schemas.Type, scope nameScope,
t *schemas.Type,
scope nameScope,
) (codegen.Type, error) {
typeIndex := 0

Expand Down Expand Up @@ -531,20 +535,71 @@ func (g *schemaGenerator) generateStructType(
structType.AddField(structField)
}

// Checking .Not here because `false` is unmarshalled to .Not = Type{}.
if t.AdditionalProperties != nil && t.AdditionalProperties.Not == nil {
// checking .Not here because `false` is unmarshalled to .Not = Type{}
if valueType, err := g.generateType(t.AdditionalProperties, nil); err != nil {
return nil, err
} else {
structType.AddField(
codegen.StructField{
Name: "AdditionalProperties",
DefaultValue: map[string]interface{}{},
SchemaType: &schemas.Type{},
Type: valueType,
},
)
if len(t.AdditionalProperties.Type) > 1 {
return nil, errTooManyTypesForAdditionalProperties
}

var (
defaultValue any = nil
fieldType codegen.Type = codegen.EmptyInterfaceType{}
)

if len(t.AdditionalProperties.Type) == 1 {
switch t.AdditionalProperties.Type[0] {
case schemas.TypeNameString:
defaultValue = map[string]string{}
fieldType = codegen.MapType{
KeyType: codegen.PrimitiveType{Type: "string"},
ValueType: codegen.PrimitiveType{Type: "string"},
}

case schemas.TypeNameArray:
defaultValue = map[string][]any{}
fieldType = codegen.MapType{
KeyType: codegen.PrimitiveType{Type: "string"},
ValueType: codegen.ArrayType{Type: codegen.EmptyInterfaceType{}},
}

case schemas.TypeNameNumber:
defaultValue = map[string]float64{}
fieldType = codegen.MapType{
KeyType: codegen.PrimitiveType{Type: "string"},
ValueType: codegen.PrimitiveType{Type: "float64"},
}

case schemas.TypeNameInteger:
defaultValue = map[string]int{}
fieldType = codegen.MapType{
KeyType: codegen.PrimitiveType{Type: "string"},
ValueType: codegen.PrimitiveType{Type: "int"},
}

case schemas.TypeNameBoolean:
defaultValue = map[string]bool{}
fieldType = codegen.MapType{
KeyType: codegen.PrimitiveType{Type: "string"},
ValueType: codegen.PrimitiveType{Type: "bool"},
}

default:
defaultValue = map[string]any{}
fieldType = codegen.MapType{
KeyType: codegen.PrimitiveType{Type: "string"},
ValueType: codegen.EmptyInterfaceType{},
}
}
}

structType.AddField(
codegen.StructField{
Name: "AdditionalProperties",
DefaultValue: defaultValue,
SchemaType: &schemas.Type{},
Type: fieldType,
},
)
}

return &structType, nil
Expand Down
30 changes: 30 additions & 0 deletions tests/data/core/additionalProperties/arrayAdditionalProperties.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": {"type": "array"}
}
30 changes: 30 additions & 0 deletions tests/data/core/additionalProperties/boolAdditionalProperties.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions tests/data/core/additionalProperties/boolAdditionalProperties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": {"type": "boolean"}
}
30 changes: 30 additions & 0 deletions tests/data/core/additionalProperties/intAdditionalProperties.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions tests/data/core/additionalProperties/intAdditionalProperties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": {"type": "integer"}
}
30 changes: 30 additions & 0 deletions tests/data/core/additionalProperties/numberAdditionalProperties.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": {"type": "number"}
}
30 changes: 30 additions & 0 deletions tests/data/core/additionalProperties/objectAdditionalProperties.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": {"type": "object"}
}
30 changes: 30 additions & 0 deletions tests/data/core/additionalProperties/stringAdditionalProperties.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"additionalProperties": {"type": "string"}
}
24 changes: 2 additions & 22 deletions tests/data/regressions/issue51/issue51.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0b49bf8

Please sign in to comment.