diff --git a/.gitignore b/.gitignore index 7e9b500..792ca00 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,6 @@ _testmain.go *.prof *.test *.out +*.txt cover.html README.html \ No newline at end of file diff --git a/baked_in.go b/baked_in.go index 46cf022..5a7435a 100644 --- a/baked_in.go +++ b/baked_in.go @@ -252,13 +252,45 @@ func contains(v *Validate, topStruct reflect.Value, currentStruct reflect.Value, func isNeField(v *Validate, topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { - _, currentKind, ok := v.getStructFieldOK(currentStruct, param) + currentField, currentKind, ok := v.getStructFieldOK(currentStruct, param) if !ok || currentKind != fieldKind { return true } - return !isEqField(v, topStruct, currentStruct, field, fieldType, fieldKind, param) + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() != currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() != currentField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() != currentField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) != int64(currentField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return true + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return !fieldTime.Equal(t) + } + + } + + // default reflect.String: + return field.String() != currentField.String() } func isNe(v *Validate, topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { @@ -431,12 +463,43 @@ func isGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect. func isNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { - _, currentKind, ok := v.getStructFieldOK(topStruct, param) + topField, currentKind, ok := v.getStructFieldOK(topStruct, param) if !ok || currentKind != fieldKind { return true } - return !isEqCrossStructField(v, topStruct, current, field, fieldType, fieldKind, param) + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return topField.Int() != field.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return topField.Uint() != field.Uint() + + case reflect.Float32, reflect.Float64: + return topField.Float() != field.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(topField.Len()) != int64(field.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return true + } + + if fieldType == timeType { + + t := field.Interface().(time.Time) + fieldTime := topField.Interface().(time.Time) + + return !fieldTime.Equal(t) + } + } + + // default reflect.String: + return topField.String() != field.String() } func isEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { diff --git a/validator_test.go b/validator_test.go index eca7baf..22084b4 100644 --- a/validator_test.go +++ b/validator_test.go @@ -2914,6 +2914,9 @@ func TestIsNeFieldValidation(t *testing.T) { errs = validate.FieldWithValue(nil, 1, "nefield") Equal(t, errs, nil) + errs = validate.FieldWithValue(sv, now, "nefield") + Equal(t, errs, nil) + type Test2 struct { Start *time.Time `validate:"nefield=NonExistantField"` End *time.Time