Open jamietanna opened 4 months ago
Hey @jamietanna, thanks for opening this issue. I am not sure I understand this use-case, could you elaborate a bit more please? eg: why would additional properties need to be omitted? and how does including them causes the failure in capturing the required fields?
Perhaps a full marshaling+unmarshaling example could help, thanks! 😁
I'm facing the same problem, no additionalProperties
are being unmarshalled, rendering them unusable.
E.g. having a schema.json
{
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"property1": {
"type": "string"
},
"property2": {
"type": "number"
}
}
},
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "string"
}
}
}
after calling go-jsonschema schema.json --output schema.go --package gen --tags yaml --extra-imports
the Go code is:
// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.
package gen
import "encoding/json"
import yaml "gopkg.in/yaml.v3"
type TestJson struct {
// Bar corresponds to the JSON schema field "bar".
Bar *string `yaml:"bar,omitempty"`
// Foo corresponds to the JSON schema field "foo".
Foo *string `yaml:"foo,omitempty"`
AdditionalProperties map[string]interface{}
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *TestJson) UnmarshalJSON(b []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(b, &raw); err != nil {
return err
}
type Plain TestJson
var plain Plain
if err := json.Unmarshal(b, &plain); err != nil {
return err
}
if v, ok := raw[""]; !ok || v == nil {
plain.AdditionalProperties = map[string]interface{}{}
}
*j = TestJson(plain)
return nil
}
// UnmarshalYAML implements yaml.Unmarshaler.
func (j *TestJson) UnmarshalYAML(value *yaml.Node) error {
var raw map[string]interface{}
if err := value.Decode(&raw); err != nil {
return err
}
type Plain TestJson
var plain Plain
if err := value.Decode(&plain); err != nil {
return err
}
if v, ok := raw[""]; !ok || v == nil {
plain.AdditionalProperties = map[string]interface{}{}
}
*j = TestJson(plain)
return nil
}
Then a test unmarshalling the following test.yaml
:
foo: "foo value"
bar: "bar value"
property1: "additional property 1"
property2: "additional property 2"
fails since "property1" and "property2" are not read into Go struct.
Go test code:
t.Run("test", func(t *testing.T) {
var yamlNode yaml3.Node
file, _ := os.ReadFile("test.yaml")
yaml3.Unmarshal(file, &yamlNode)
genStruct := gen.TestJson{}
genStruct.UnmarshalYAML(&yamlNode)
if len(genStruct.AdditionalProperties) == 0 {
t.Fatalf("no additional properties")
}
})
hey @jamietanna @apodznoev I pushed this pr out, mind to have a look at it and see if it resolves the problems you noted? #278 thanks!
At least for JSON and YAML, I'd expect:
Would convert into the following Go:
But instead we see:
Which means that (un)marshaling fails to capture the required fields