Compare commits

..

No commits in common. "e0d73b537145d4ab0efb771b82f0c16fc99fc033" and "3252e0dde7feaa4fa8fb57f9c57f0909b850b271" have entirely different histories.

3 changed files with 7 additions and 93 deletions

View file

@ -1,31 +1,11 @@
# go-jsonschema
A [JSON schema] code generator for Go.
JSON schema draft 2020-12 is supported.
A JSON schema code generator for Go.
## Usage
jsonschemagen -s <schema> -o <output>
One Go type per definition will be generated.
- `int64` is used for `"type": "integer"`.
- `json.Number` is used for `"type": "number"`.
- Go structs are generated for objects with `"additionalProperties": false`.
- `json.RawMessage` is used when a value can have multiple types. Helpers are
generated for `allOf`, `anyOf`, `oneOf`, `then`, `else` and `dependantSchemas`
which are references.
## Contributing
Report bugs and send patches to the [mailing list]. Discuss in [#emersion] on
Libera Chat.
## License
MIT
[JSON schema]: https://json-schema.org/
[mailing list]: https://lists.sr.ht/~emersion/public-inbox
[#emersion]: ircs://irc.libera.chat/#emersion

View file

@ -52,11 +52,8 @@ func resolveRef(def *jsonschema.Schema, root *jsonschema.Schema) *jsonschema.Sch
}
func schemaType(schema *jsonschema.Schema) jsonschema.Type {
switch {
case len(schema.Type) == 1:
return schema.Type[0]
case len(schema.Type) > 0:
return ""
if schema.Type != "" {
return schema.Type
}
var v interface{}
@ -128,40 +125,9 @@ func noAdditionalProps(schema *jsonschema.Schema) bool {
return schema.AdditionalProperties != nil && schema.AdditionalProperties.IsFalse()
}
// unwrapNullableSchema unwraps a schema in the form:
//
// {
// "oneOf": {
// { "type": "null" },
// <sub-schema>
// }
// }
func unwrapNullableSchema(schema *jsonschema.Schema) (*jsonschema.Schema, bool) {
for _, choices := range [][]jsonschema.Schema{schema.AnyOf, schema.OneOf} {
if len(choices) != 2 {
continue
}
nullIndex := -1
for i, choice := range choices {
if len(choice.Type) == 1 && choice.Type[0] == jsonschema.TypeNull {
nullIndex = i
break
}
}
if nullIndex < 0 {
continue
}
otherIndex := (nullIndex + 1) % 2
return &choices[otherIndex], true
}
return nil, false
}
func generateSchemaType(schema *jsonschema.Schema, root *jsonschema.Schema, required bool) jen.Code {
if schema == nil {
schema = &jsonschema.Schema{}
return jen.Interface()
}
refName := refName(schema.Ref)
@ -174,10 +140,6 @@ func generateSchemaType(schema *jsonschema.Schema, root *jsonschema.Schema, requ
return t
}
if subschema, ok := unwrapNullableSchema(schema); ok {
return jen.Op("*").Add(generateSchemaType(subschema, root, true))
}
switch schemaType(schema) {
case jsonschema.TypeNull:
return jen.Struct()
@ -186,7 +148,7 @@ func generateSchemaType(schema *jsonschema.Schema, root *jsonschema.Schema, requ
case jsonschema.TypeArray:
return jen.Index().Add(generateSchemaType(schema.Items, root, required))
case jsonschema.TypeNumber:
return jen.Qual("encoding/json", "Number")
return jen.Float64()
case jsonschema.TypeString:
return jen.String()
case jsonschema.TypeInteger:
@ -227,15 +189,6 @@ func generateDef(schema *jsonschema.Schema, root *jsonschema.Schema, f *jen.File
for _, child := range schema.OneOf {
children = append(children, child)
}
if schema.Then != nil {
children = append(children, *schema.Then)
}
if schema.Else != nil {
children = append(children, *schema.Else)
}
for _, child := range schema.DependentSchemas {
children = append(children, child)
}
for _, child := range children {
refName := refName(child.Ref)

View file

@ -17,25 +17,6 @@ const (
TypeInteger Type = "integer"
)
type TypeSet []Type
func (ts *TypeSet) UnmarshalJSON(b []byte) error {
if b[0] == '[' {
type rawTypeSet TypeSet
out := (*rawTypeSet)(ts)
return json.Unmarshal(b, out)
} else {
var t Type
err := json.Unmarshal(b, &t)
if err != nil {
*ts = nil
} else {
*ts = []Type{t}
}
return err
}
}
type Schema struct {
// Core
Schema string `json:"$schema"`
@ -70,7 +51,7 @@ type Schema struct {
PropertyNames *Schema `json:"propertyNames"`
// Validation
Type TypeSet `json:"type"`
Type Type `json:"type"`
Enum []interface{} `json:"enum"`
Const interface{} `json:"const"`
@ -111,7 +92,7 @@ type Schema struct {
func (schema *Schema) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte("true")) {
*schema = Schema{}
// Nothing to do
} else if bytes.Equal(b, []byte("false")) {
*schema = Schema{Not: []Schema{
Schema{},