-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcombinations.go
135 lines (115 loc) · 3.13 KB
/
combinations.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
123
124
125
126
127
128
129
130
131
132
133
134
135
package jsval
import (
"errors"
"github.com/lestrrat-go/pdebug"
)
func (c *comboconstraint) Add(v Constraint) {
c.constraints = append(c.constraints, v)
}
func (c *comboconstraint) Constraints() []Constraint {
return c.constraints
}
func reduceCombined(cc interface {
Constraint
Constraints() []Constraint
}) Constraint {
l := cc.Constraints()
if len(l) == 1 {
return l[0]
}
return cc
}
// Any creates a new AnyConstraint
func Any() *AnyConstraint {
return &AnyConstraint{}
}
// Reduce returns the child Constraint, if this constraint
// has only 1 child constraint.
func (c *AnyConstraint) Reduce() Constraint {
return reduceCombined(c)
}
// Add appends a new Constraint
func (c *AnyConstraint) Add(c2 Constraint) *AnyConstraint {
c.comboconstraint.Add(c2)
return c
}
// Validate validates the value against the input value.
// For AnyConstraints, it will return success the moment
// one child Constraint succeeds. It will return an error
// if none of the child Constraints succeeds
func (c *AnyConstraint) Validate(v interface{}) (err error) {
if pdebug.Enabled {
g := pdebug.Marker("AnyConstraint.Validate").BindError(&err)
defer g.End()
}
for _, celem := range c.constraints {
if err := celem.Validate(v); err == nil {
return nil
}
}
return errors.New("could not validate against any of the constraints")
}
// All creates a new AllConstraint
func All() *AllConstraint {
return &AllConstraint{}
}
// Reduce returns the child Constraint, if this constraint
// has only 1 child constraint.
func (c *AllConstraint) Reduce() Constraint {
return reduceCombined(c)
}
// Add appends a new Constraint
func (c *AllConstraint) Add(c2 Constraint) *AllConstraint {
c.comboconstraint.Add(c2)
return c
}
// Validate validates the value against the input value.
// For AllConstraints, it will only return success if
// all of the child Constraints succeeded.
func (c *AllConstraint) Validate(v interface{}) (err error) {
if pdebug.Enabled {
g := pdebug.Marker("AllConstraint.Validate").BindError(&err)
defer g.End()
}
for _, celem := range c.constraints {
if err := celem.Validate(v); err != nil {
return err
}
}
return nil
}
// OneOf creates a new OneOfConstraint
func OneOf() *OneOfConstraint {
return &OneOfConstraint{}
}
// Reduce returns the child Constraint, if this constraint
// has only 1 child constraint.
func (c *OneOfConstraint) Reduce() Constraint {
return reduceCombined(c)
}
// Add appends a new Constraint
func (c *OneOfConstraint) Add(c2 Constraint) *OneOfConstraint {
c.comboconstraint.Add(c2)
return c
}
// Validate validates the value against the input value.
// For OneOfConstraints, it will return success only if
// exactly 1 child Constraint succeeds.
func (c *OneOfConstraint) Validate(v interface{}) (err error) {
if pdebug.Enabled {
g := pdebug.Marker("OneOfConstraint.Validate").BindError(&err)
defer g.End()
}
count := 0
for _, celem := range c.constraints {
if err := celem.Validate(v); err == nil {
count++
}
}
if count == 0 {
return errors.New("none of the constraints passed")
} else if count > 1 {
return errors.New("more than 1 of the constraints passed")
}
return nil // Yes!
}