go-jsonschema/schema.go

123 lines
3.8 KiB
Go
Raw Normal View History

2022-10-06 08:23:55 +01:00
package jsonschema
import (
"bytes"
"encoding/json"
)
type Type string
const (
TypeNull Type = "null"
TypeBoolean Type = "boolean"
TypeObject Type = "object"
TypeArray Type = "array"
TypeNumber Type = "number"
TypeString Type = "string"
TypeInteger Type = "integer"
)
type Schema struct {
// Core
Schema string `json:"$schema"`
Vocabulary map[string]bool `json:"$vocabulary"`
ID string `json:"$id"`
Ref string `json:"$ref"`
DynamicRef string `json:"$dynamicRef"`
Defs map[string]Schema `json:"$defs"`
Comment string `json:"$comment"`
// Applying subschemas with logic
AllOf []Schema `json:"allOf"`
AnyOf []Schema `json:"anyOf"`
OneOf []Schema `json:"oneOf"`
Not []Schema `json:"not"`
// Applying subschemas conditionally
If *Schema `json:"if"`
Then *Schema `json:"then"`
Else *Schema `json:"else"`
DependentSchemas map[string]Schema `json:"dependentSchemas"`
// Applying subschemas to arrays
PrefixItems []Schema `json:"prefixItems"`
Items *Schema `json:"items"`
Contains *Schema `json:"contains"`
// Applying subschemas to objects
Properties map[string]Schema `json:"properties"`
PatternProperties map[string]Schema `json:"patternProperties"`
AdditionalProperties *Schema `json:"additionalProperties"`
PropertyNames *Schema `json:"propertyNames"`
// Validation
Type Type `json:"type"`
Enum []interface{} `json:"enum"`
Const interface{} `json:"const"`
// Validation for numbers
MultipleOf json.Number `json:"multipleOf"`
Maximum json.Number `json:"maximum"`
ExclusiveMaximum json.Number `json:"exclusiveMaximum"`
Minimum json.Number `json:"minimum"`
ExclusiveMinimum json.Number `json:"exclusiveMinimum"`
// Validation for strings
MaxLength int `json:"maxLength"`
MinLength int `json:"minLength"`
Pattern string `json:"pattern"`
// Validation for arrays
MaxItems int `json:"maxItems"`
MinItems int `json:"minItems"`
UniqueItems bool `json:"uniqueItems"`
MaxContains int `json:"maxContains"`
MinContains int `json:"minContains"`
// Validation for objects
MaxProperties int `json:"maxProperties"`
MinProperties int `json:"minProperties"`
Required []string `json:"required"`
DependentRequired map[string][]string `json:"dependentRequired"`
// Basic metadata annotations
Title string `json:"title"`
Description string `json:"description"`
Default interface{} `json:"default"`
Deprecated bool `json:"deprecated"`
ReadOnly bool `json:"readOnly"`
WriteOnly bool `json:"writeOnly"`
Examples []interface{} `json:"examples"`
}
func (schema *Schema) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte("true")) {
// Nothing to do
} else if bytes.Equal(b, []byte("false")) {
*schema = Schema{Not: []Schema{
Schema{},
}}
} else {
type rawSchema Schema
var out rawSchema
if err := json.Unmarshal(b, &out); err != nil {
return err
}
*schema = Schema(out)
}
return nil
}
func (schema *Schema) IsTrue() bool {
return len(schema.AllOf) == 0 && len(schema.AnyOf) == 0 && len(schema.OneOf) == 0 && len(schema.Not) == 0 && schema.If == nil && schema.Then == nil && schema.Else == nil && len(schema.DependentSchemas) == 0 && len(schema.PrefixItems) == 0 && schema.Items == nil && schema.Contains == nil && len(schema.Properties) == 0 && len(schema.PatternProperties) == 0 && schema.AdditionalProperties == nil && schema.PropertyNames == nil
}
func (schema *Schema) IsFalse() bool {
for _, not := range schema.Not {
if not.IsTrue() {
return true
}
}
return false
}