|
|
|
@ -16,10 +16,12 @@ var BakedInValidators = map[string]Func{ |
|
|
|
|
"len": hasLengthOf, |
|
|
|
|
"min": hasMinOf, |
|
|
|
|
"max": hasMaxOf, |
|
|
|
|
"eq": isEq, |
|
|
|
|
"lt": isLt, |
|
|
|
|
"lte": isLte, |
|
|
|
|
"gt": isGt, |
|
|
|
|
"gte": isGte, |
|
|
|
|
"eqfield": isEqField, |
|
|
|
|
"gtefield": isGteField, |
|
|
|
|
"gtfield": isGtField, |
|
|
|
|
"ltefield": isLteField, |
|
|
|
@ -40,6 +42,119 @@ var BakedInValidators = map[string]Func{ |
|
|
|
|
"base64": isBase64, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func isEqField(top interface{}, current interface{}, field interface{}, param string) bool { |
|
|
|
|
|
|
|
|
|
if current == nil { |
|
|
|
|
panic("struct not passed for cross validation") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
currentVal := reflect.ValueOf(current) |
|
|
|
|
|
|
|
|
|
if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() { |
|
|
|
|
currentVal = reflect.ValueOf(currentVal.Elem().Interface()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var currentFielVal reflect.Value |
|
|
|
|
|
|
|
|
|
switch currentVal.Kind() { |
|
|
|
|
|
|
|
|
|
case reflect.Struct: |
|
|
|
|
|
|
|
|
|
if currentVal.Type() == reflect.TypeOf(time.Time{}) { |
|
|
|
|
currentFielVal = currentVal |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
f := currentVal.FieldByName(param) |
|
|
|
|
|
|
|
|
|
if f.Kind() == reflect.Invalid { |
|
|
|
|
panic(fmt.Sprintf("Field \"%s\" not found in struct", param)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
currentFielVal = f |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
|
|
currentFielVal = currentVal |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() { |
|
|
|
|
|
|
|
|
|
currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fv := reflect.ValueOf(field) |
|
|
|
|
|
|
|
|
|
switch fv.Kind() { |
|
|
|
|
|
|
|
|
|
case reflect.String: |
|
|
|
|
return fv.String() == currentFielVal.String() |
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
|
|
|
|
|
|
|
|
|
return fv.Int() == currentFielVal.Int() |
|
|
|
|
|
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: |
|
|
|
|
|
|
|
|
|
return fv.Uint() == currentFielVal.Uint() |
|
|
|
|
|
|
|
|
|
case reflect.Float32, reflect.Float64: |
|
|
|
|
|
|
|
|
|
return fv.Float() == currentFielVal.Float() |
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array: |
|
|
|
|
|
|
|
|
|
return int64(fv.Len()) == int64(currentFielVal.Len()) |
|
|
|
|
case reflect.Struct: |
|
|
|
|
|
|
|
|
|
if fv.Type() == reflect.TypeOf(time.Time{}) { |
|
|
|
|
|
|
|
|
|
if currentFielVal.Type() != reflect.TypeOf(time.Time{}) { |
|
|
|
|
panic("Bad Top Level field type") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
t := currentFielVal.Interface().(time.Time) |
|
|
|
|
fieldTime := field.(time.Time) |
|
|
|
|
|
|
|
|
|
return fieldTime.Equal(t) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func isEq(top interface{}, current interface{}, field interface{}, param string) bool { |
|
|
|
|
|
|
|
|
|
st := reflect.ValueOf(field) |
|
|
|
|
|
|
|
|
|
switch st.Kind() { |
|
|
|
|
|
|
|
|
|
case reflect.String: |
|
|
|
|
|
|
|
|
|
return st.String() == param |
|
|
|
|
|
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array: |
|
|
|
|
p := asInt(param) |
|
|
|
|
|
|
|
|
|
return int64(st.Len()) == p |
|
|
|
|
|
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
|
|
|
|
p := asInt(param) |
|
|
|
|
|
|
|
|
|
return st.Int() == p |
|
|
|
|
|
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: |
|
|
|
|
p := asUint(param) |
|
|
|
|
|
|
|
|
|
return st.Uint() == p |
|
|
|
|
|
|
|
|
|
case reflect.Float32, reflect.Float64: |
|
|
|
|
p := asFloat(param) |
|
|
|
|
|
|
|
|
|
return st.Float() == p |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func isBase64(top interface{}, current interface{}, field interface{}, param string) bool { |
|
|
|
|
return matchesRegex(base64Regex, field) |
|
|
|
|
} |
|
|
|
|