Skip to content

Commit

Permalink
feat(refs): first signs of life on refs working properly
Browse files Browse the repository at this point in the history
  • Loading branch information
b5 committed Jan 16, 2018
1 parent 5ab22c8 commit 435c766
Show file tree
Hide file tree
Showing 10 changed files with 555 additions and 68 deletions.
13 changes: 11 additions & 2 deletions keywords.go
Expand Up @@ -123,9 +123,9 @@ type Enum []Const
func (e Enum) String() string {
str := "["
for _, c := range e {
str += ", " + c.String()
str += c.String() + ", "
}
return str + "]"
return str[:len(str)-2] + "]"
}

// Validate implements the Validator interface for Enum
Expand All @@ -150,6 +150,15 @@ func (e Enum) JSONProp(name string) interface{} {
return e[idx]
}

// JSONChildren implements the JSONContainer interface for Enum
func (e Enum) JSONChildren() (res map[string]JSONPather) {
res = map[string]JSONPather{}
for i, bs := range e {
res[strconv.Itoa(i)] = bs
}
return
}

// Const MAY be of any type, including null.
// An instance validates successfully against this keyword if its
// value is equal to the value of the keyword.
Expand Down
13 changes: 13 additions & 0 deletions keywords_arrays.go
Expand Up @@ -121,6 +121,14 @@ func (a *AdditionalItems) JSONProp(name string) interface{} {
return a.Schema.JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for AdditionalItems
func (a *AdditionalItems) JSONChildren() (res map[string]JSONPather) {
if a.Schema == nil {
return map[string]JSONPather{}
}
return a.Schema.JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for AdditionalItems
func (a *AdditionalItems) UnmarshalJSON(data []byte) error {
sch := &Schema{}
Expand Down Expand Up @@ -207,6 +215,11 @@ func (c Contains) JSONProp(name string) interface{} {
return Schema(c).JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for Contains
func (c Contains) JSONChildren() (res map[string]JSONPather) {
return Schema(c).JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for Contains
func (c *Contains) UnmarshalJSON(data []byte) error {
var sch Schema
Expand Down
9 changes: 9 additions & 0 deletions keywords_booleans.go
Expand Up @@ -139,6 +139,15 @@ func (n Not) JSONProp(name string) interface{} {
return Schema(n).JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for Not
func (n Not) JSONChildren() (res map[string]JSONPather) {
if n.Ref != "" {
s := Schema(n)
return map[string]JSONPather{"$ref": &s}
}
return Schema(n).JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for Not
func (n *Not) UnmarshalJSON(data []byte) error {
var sch Schema
Expand Down
15 changes: 15 additions & 0 deletions keywords_conditionals.go
Expand Up @@ -37,6 +37,11 @@ func (i If) JSONProp(name string) interface{} {
return Schema(i.Schema).JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for If
func (i If) JSONChildren() (res map[string]JSONPather) {
return i.Schema.JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for If
func (i *If) UnmarshalJSON(data []byte) error {
var sch Schema
Expand All @@ -62,6 +67,11 @@ func (t Then) JSONProp(name string) interface{} {
return Schema(t).JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for If
func (t Then) JSONChildren() (res map[string]JSONPather) {
return Schema(t).JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for Then
func (t *Then) UnmarshalJSON(data []byte) error {
var sch Schema
Expand All @@ -87,6 +97,11 @@ func (e Else) JSONProp(name string) interface{} {
return Schema(e).JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for Else
func (e Else) JSONChildren() (res map[string]JSONPather) {
return Schema(e).JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for Else
func (e *Else) UnmarshalJSON(data []byte) error {
var sch Schema
Expand Down
93 changes: 89 additions & 4 deletions keywords_objects.go
Expand Up @@ -144,6 +144,15 @@ func (p PatternProperties) JSONProp(name string) interface{} {
return nil
}

// JSONChildren implements the JSONContainer interface for PatternProperties
func (p PatternProperties) JSONChildren() (res map[string]JSONPather) {
res = map[string]JSONPather{}
for i, pp := range p {
res[strconv.Itoa(i)] = pp.schema
}
return
}

// UnmarshalJSON implements the json.Unmarshaler interface for PatternProperties
func (p *PatternProperties) UnmarshalJSON(data []byte) error {
var props map[string]*Schema
Expand Down Expand Up @@ -178,7 +187,7 @@ func (p *PatternProperties) UnmarshalJSON(data []byte) error {
type AdditionalProperties struct {
properties *Properties
patterns *PatternProperties
Schema Schema
Schema *Schema
}

// Validate implements the validator interface for AdditionalProperties
Expand Down Expand Up @@ -210,14 +219,28 @@ func (ap AdditionalProperties) Validate(data interface{}) error {

// UnmarshalJSON implements the json.Unmarshaler interface for AdditionalProperties
func (ap *AdditionalProperties) UnmarshalJSON(data []byte) error {
var sch Schema
if err := json.Unmarshal(data, &sch); err != nil {
sch := &Schema{}
if err := json.Unmarshal(data, sch); err != nil {
return err
}
// fmt.Println("unmarshal:", sch.Ref)
*ap = AdditionalProperties{Schema: sch}
return nil
}

// JSONProp implements JSON property name indexing for AdditionalProperties
func (ap *AdditionalProperties) JSONProp(name string) interface{} {
return ap.Schema.JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for AdditionalProperties
func (ap *AdditionalProperties) JSONChildren() (res map[string]JSONPather) {
if ap.Schema.Ref != "" {
return map[string]JSONPather{"$ref": ap.Schema}
}
return ap.Schema.JSONChildren()
}

// Dependencies : [CREF1]
// This keyword specifies rules that are evaluated if the instance is an object and contains a
// certain property.
Expand All @@ -229,10 +252,18 @@ func (ap *AdditionalProperties) UnmarshalJSON(data []byte) error {
// and MUST be unique. If the dependency key is a property in the instance, each of the items
// in the dependency value must be a property that exists in the instance.
// Omitting this keyword has the same behavior as an empty object.
type Dependencies map[string][]*Schema
type Dependencies map[string]Dependency

// Validate implements the validator interface for Dependencies
func (d Dependencies) Validate(data interface{}) error {
if obj, ok := data.(map[string]interface{}); ok {
for key, val := range d {
// fmt.Println(key, obj[key])
if obj[key] != nil {
val.Validate(obj)
}
}
}
return nil
}

Expand All @@ -241,6 +272,55 @@ func (d Dependencies) JSONProp(name string) interface{} {
return d[name]
}

// JSONChildren implements the JSONContainer interface for Dependencies
// func (d Dependencies) JSONChildren() (res map[string]JSONPather) {
// res = map[string]JSONPather{}
// for key, dep := range d {
// if dep.schema != nil {
// res[key] = dep.schema
// }
// }
// return
// }

// Dependency is an instance used only in the dependencies proprty
type Dependency struct {
schema *Schema
props []string
}

// Validate implements the validator interface for Dependency
func (d Dependency) Validate(data interface{}) error {
if obj, ok := data.(map[string]interface{}); ok {
if d.schema != nil {
return d.schema.Validate(data)
} else if len(d.props) > 0 {
for _, k := range d.props {
if obj[k] == nil {
return fmt.Errorf("dependency property %s is required", k)
}
}
}
}
return nil
}

// UnmarshalJSON implements the json.Unmarshaler interface for Dependencies
func (d *Dependency) UnmarshalJSON(data []byte) error {
props := []string{}
if err := json.Unmarshal(data, &props); err == nil {
*d = Dependency{props: props}
return nil
}
sch := &Schema{}
err := json.Unmarshal(data, sch)

if err == nil {
*d = Dependency{schema: sch}
}
return err
}

// PropertyNames checks if every property name in the instance validates against the provided schema
// if the instance is an object.
// Note the property name that the schema is testing will always be a string.
Expand All @@ -265,6 +345,11 @@ func (p PropertyNames) JSONProp(name string) interface{} {
return Schema(p).JSONProp(name)
}

// JSONChildren implements the JSONContainer interface for PropertyNames
func (p PropertyNames) JSONChildren() (res map[string]JSONPather) {
return Schema(p).JSONChildren()
}

// UnmarshalJSON implements the json.Unmarshaler interface for PropertyNames
func (p *PropertyNames) UnmarshalJSON(data []byte) error {
var sch Schema
Expand Down

0 comments on commit 435c766

Please sign in to comment.