in pkg/validation/validate/schema.go [109:175]
func (s *SchemaValidator) Validate(data interface{}) *Result {
result := new(Result)
if s == nil {
return result
}
if data == nil {
result.Merge(s.validators[0].Validate(data)) // type validator
result.Merge(s.validators[6].Validate(data)) // common validator
return result
}
tpe := reflect.TypeOf(data)
kind := tpe.Kind()
for kind == reflect.Ptr {
tpe = tpe.Elem()
kind = tpe.Kind()
}
d := data
if kind == reflect.Struct {
// NOTE: since reflect retrieves the true nature of types
// this means that all strfmt types passed here (e.g. strfmt.Datetime, etc..)
// are converted here to strings, and structs are systematically converted
// to map[string]interface{}.
d = swag.ToDynamicJSON(data)
}
// TODO: this part should be handed over to type validator
// Handle special case of json.Number data (number marshalled as string)
isnumber := s.Schema.Type.Contains(numberType) || s.Schema.Type.Contains(integerType)
if num, ok := data.(json.Number); ok && isnumber {
if s.Schema.Type.Contains(integerType) { // avoid lossy conversion
in, erri := num.Int64()
if erri != nil {
result.AddErrors(invalidTypeConversionMsg(s.Path, erri))
result.Inc()
return result
}
d = in
} else {
nf, errf := num.Float64()
if errf != nil {
result.AddErrors(invalidTypeConversionMsg(s.Path, errf))
result.Inc()
return result
}
d = nf
}
tpe = reflect.TypeOf(d)
kind = tpe.Kind()
}
for _, v := range s.validators {
if !v.Applies(s.Schema, kind) {
debugLog("%T does not apply for %v", v, kind)
continue
}
err := v.Validate(d)
result.Merge(err)
result.Inc()
}
result.Inc()
return result
}