81
80
// RegisterVocabulary is defined on Validator.
82
81
func (v *validator) RegisterVocabulary(attributeName string, allowedValues interface{}) {
83
v.vocab[attributeName] = convertToSlice(allowedValues)
82
v.vocab[resolveAlias(attributeName)] = convertToSlice(allowedValues)
86
85
var checkIsCollection = func(coll interface{}) {
103
102
// UpdateVocabulary is defined on Validator.
104
103
func (v *validator) UpdateVocabulary(attributeName string, allowedValues interface{}) {
104
attributeName = resolveAlias(attributeName)
105
105
// If this attribute is not registered, delegate to RegisterVocabulary()
106
106
currentValues, ok := v.vocab[attributeName]
126
126
func (v *validator) updateVocabularyFromMap(attributeName string, valuesMap map[interface{}]bool) {
127
attributeName = resolveAlias(attributeName)
127
128
var merged []interface{}
128
129
for one, _ := range valuesMap {
129
130
// TODO (anastasiamac) Because it's coming from the map, the order maybe affected
186
187
// checkInVocab returns an error if the attribute value is not allowed by the
187
188
// vocab which may have been registered for it.
188
189
func (v *validator) checkInVocab(attributeName string, attributeValue interface{}) error {
189
validValues, ok := v.vocab[attributeName]
190
validValues, ok := v.vocab[resolveAlias(attributeName)]
199
200
"invalid constraint value: %v=%v\nvalid values are: %v", attributeName, attributeValue, validValues)
202
// coerce returns v in a format that allows constraint values to be easily compared.
203
// Its main purpose is to cast all numeric values to int64 or float64.
203
// coerce returns v in a format that allows constraint values to be easily
204
// compared. Its main purpose is to cast all numeric values to float64 (since
205
// the numbers we compare are generated from json serialization).
204
206
func coerce(v interface{}) interface{} {
206
switch vv := reflect.TypeOf(v); vv.Kind() {
209
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
210
return int64(reflect.ValueOf(v).Int())
211
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
212
uval := reflect.ValueOf(v).Uint()
213
// Just double check the value is in range.
214
if uval > math.MaxInt64 {
215
panic(fmt.Errorf("constraint value %v is too large", uval))
218
case reflect.Float32, reflect.Float64:
219
return float64(reflect.ValueOf(v).Float())
207
switch val := v.(type) {
210
// Yes, these are all the same, however we can't put them into a single
211
// case, or the value becomes interface{}, which can't be converted to a
225
241
// withFallbacks returns a copy of v with nil values taken from vFallback.
226
242
func withFallbacks(v Value, vFallback Value) Value {
228
for _, fieldName := range fieldNames {
229
resultVal := reflect.ValueOf(&result).Elem().FieldByName(fieldName)
230
val := reflect.ValueOf(&v).Elem().FieldByName(fieldName)
243
vAttr := v.attributesWithValues()
244
fbAttr := vFallback.attributesWithValues()
245
for k, v := range fbAttr {
246
if _, ok := vAttr[k]; !ok {
250
return fromAttributes(vAttr)
238
253
// Validate is defined on Validator.
266
281
// Null out the conflicting consFallback attribute values because
267
282
// cons takes priority. We can't error here because we
268
283
// know that aConflicts contains valid attr names.
269
consFallbackMinusConflicts, _ := consFallback.without(fallbackConflicts...)
284
consFallbackMinusConflicts := consFallback.without(fallbackConflicts...)
270
285
// The result is cons with fallbacks coming from any
271
286
// non conflicting consFallback attributes.
272
287
return withFallbacks(cons, consFallbackMinusConflicts), nil