func()

in pkg/validation/validate/type.go [132:173]


func (t *typeValidator) Validate(data interface{}) *Result {
	result := new(Result)
	result.Inc()
	if data == nil {
		// nil or zero value for the passed structure require Type: null
		if len(t.Type) > 0 && !t.Type.Contains(nullType) && !t.Nullable { // TODO: if a property is not required it also passes this
			return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), nullType))
		}
		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()

	// infer schema type (JSON) and format from passed data type
	schType, format := t.schemaInfoForType(data)

	debugLog("path: %s, schType: %s,  format: %s, expType: %s, expFmt: %s, kind: %s", t.Path, schType, format, t.Type, t.Format, val.Kind().String())

	// check numerical types
	// TODO: check unsigned ints
	// TODO: check json.Number (see schema.go)
	isLowerInt := t.Format == integerFormatInt64 && format == integerFormatInt32
	isLowerFloat := t.Format == numberFormatFloat64 && format == numberFormatFloat32
	isFloatInt := schType == numberType && swag.IsFloat64AJSONInteger(val.Float()) && t.Type.Contains(integerType)
	isIntFloat := schType == integerType && t.Type.Contains(numberType)

	if kind != reflect.String && kind != reflect.Slice && t.Format != "" && !(t.Type.Contains(schType) || format == t.Format || isFloatInt || isIntFloat || isLowerInt || isLowerFloat) {
		// TODO: test case
		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, t.Format, format))
	}

	if !(t.Type.Contains(numberType) || t.Type.Contains(integerType)) && t.Format != "" && (kind == reflect.String || kind == reflect.Slice) {
		return result
	}

	if !(t.Type.Contains(schType) || isFloatInt || isIntFloat) {
		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), schType))
	}
	return result
}