func (t *typeValidator) Validate(data interface{}) *Result { result := new(Result) result.Inc() if data == nil || reflect.DeepEqual(reflect.Zero(reflect.TypeOf(data)), reflect.ValueOf(data)) { if len(t.Type) > 0 && !t.Type.Contains("null") { // TODO: if a property is not required it also passes this return sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), "null")) } return result } // check if the type matches, should be used in every validator chain as first item val := reflect.Indirect(reflect.ValueOf(data)) kind := val.Kind() schType, format := t.schemaInfoForType(data) //fmt.Println("path:", t.Path, "schType:", schType, "format:", format, "expType:", t.Type, "expFmt:", t.Format, "kind:", val.Kind().String()) isLowerInt := t.Format == "int64" && format == "int32" isLowerFloat := t.Format == "float64" && format == "float32" isFloatInt := schType == "number" && swag.IsFloat64AJSONInteger(val.Float()) && t.Type.Contains("integer") isIntFloat := schType == "integer" && t.Type.Contains("number") if kind != reflect.String && kind != reflect.Slice && t.Format != "" && !(t.Type.Contains(schType) || format == t.Format || isFloatInt || isIntFloat || isLowerInt || isLowerFloat) { return sErr(errors.InvalidType(t.Path, t.In, t.Format, format)) } if !(t.Type.Contains("number") || t.Type.Contains("integer")) && t.Format != "" && (kind == reflect.String || kind == reflect.Slice) { return result } if !(t.Type.Contains(schType) || isFloatInt || isIntFloat) { return sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), schType)) } return result }
// MultipleOf validates if the provided number is a multiple of the factor func MultipleOf(path, in string, data, factor float64) *errors.Validation { if !swag.IsFloat64AJSONInteger(data / factor) { return errors.NotMultipleOf(path, in, factor) } return nil }