This repository has been archived by the owner on Jul 24, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
val_array.go
122 lines (110 loc) · 2.92 KB
/
val_array.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package jsonschema
import (
"encoding/json"
"fmt"
"strconv"
)
type additionalItems struct {
EmbeddedSchemas
isTrue bool
}
func (a *additionalItems) UnmarshalJSON(b []byte) error {
a.isTrue = true
if err := json.Unmarshal(b, &a.isTrue); err == nil {
return nil
}
return json.Unmarshal(b, &a.EmbeddedSchemas)
}
func (a additionalItems) Validate(keypath []string, v interface{}) []ValidationError {
return nil
}
type maxItems int
func (m maxItems) Validate(keypath []string, v interface{}) []ValidationError {
l, ok := v.([]interface{})
if !ok {
return nil
}
if len(l) > int(m) {
maxErr := ValidationError{keypath, fmt.Sprintf("Array must have fewer than %d items.", m)}
return []ValidationError{maxErr}
}
return nil
}
type minItems int
func (m minItems) Validate(keypath []string, v interface{}) []ValidationError {
l, ok := v.([]interface{})
if !ok {
return nil
}
if len(l) < int(m) {
minErr := ValidationError{keypath, fmt.Sprintf("Array must have more than %d items.", m)}
return []ValidationError{minErr}
}
return nil
}
// The spec[1] is useless for this keyword. The implemention here is based on the tests and this[2] guide.
//
// [1] http://json-schema.org/latest/json-schema-validation.html#anchor37
// [2] http://spacetelescope.github.io/understanding-json-schema/reference/array.html
type items struct {
EmbeddedSchemas
schemaSlice []*Schema
additionalAllowed bool
additionalItems *Schema
}
func (i *items) UnmarshalJSON(b []byte) error {
i.EmbeddedSchemas = make(EmbeddedSchemas)
var s Schema
if err := json.Unmarshal(b, &s); err == nil {
i.EmbeddedSchemas[""] = &s
return nil
}
if err := json.Unmarshal(b, &i.schemaSlice); err != nil {
return err
}
for index, v := range i.schemaSlice {
i.EmbeddedSchemas[strconv.Itoa(index)] = v
}
return nil
}
func (i *items) CheckNeighbors(m map[string]Node) {
i.additionalAllowed = true
v, ok := m["additionalItems"]
if !ok {
return
}
a, ok := v.Validator.(*additionalItems)
if !ok {
return
}
i.additionalAllowed = a.isTrue
i.additionalItems = a.EmbeddedSchemas[""]
return
}
func (i items) Validate(keypath []string, v interface{}) []ValidationError {
var valErrs []ValidationError
instances, ok := v.([]interface{})
if !ok {
return nil
}
if s, ok := i.EmbeddedSchemas[""]; ok {
for pos, value := range instances {
valErrs = append(valErrs, s.Validate(append(keypath, strconv.Itoa(pos)), value)...)
}
} else if len(i.schemaSlice) > 0 {
for pos, value := range instances {
if pos <= len(i.schemaSlice)-1 {
s := i.schemaSlice[pos]
valErrs = append(valErrs, s.Validate(append(keypath, strconv.Itoa(pos)), value)...)
} else if i.additionalAllowed {
if i.additionalItems == nil {
continue
}
valErrs = append(valErrs, i.additionalItems.Validate(keypath, value)...)
} else if !i.additionalAllowed {
return []ValidationError{{keypath, "Additional items aren't allowed."}}
}
}
}
return valErrs
}