update to handle nested map + Array + Slice structs

pull/161/head
joeybloggs 9 years ago
parent 3ab458c80c
commit 2ea9043764
  1. 44
      util.go
  2. 22
      validator_test.go

@ -78,8 +78,9 @@ func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (re
if idx == -1 {
ns = namespace[bracketIdx:]
} else {
ns = namespace[idx+bracketIdx:]
ns = namespace[bracketIdx:]
}
// fmt.Println("NSS2:", ns)
}
// fmt.Println("Looking for field:", fld)
@ -93,6 +94,14 @@ func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (re
case reflect.Array, reflect.Slice:
idx := strings.Index(namespace, "[")
idx2 := strings.Index(namespace, "]")
// idx3 := strings.Index(namespace, namespaceSeparator)
// if idx3 == -1 {
// idx3 = 0
// } else {
// idx3 = 1
// }
//
arrIdx, _ := strconv.Atoi(namespace[idx+1 : idx2])
@ -102,21 +111,36 @@ func (v *Validate) getStructFieldOK(current reflect.Value, namespace string) (re
return current, kind, false
}
return v.getStructFieldOK(current.Index(arrIdx), namespace[idx2+1:])
startIdx := idx2 + 1
if startIdx < len(namespace) {
if namespace[startIdx:startIdx+1] == "." {
startIdx++
}
}
return v.getStructFieldOK(current.Index(arrIdx), namespace[startIdx:])
case reflect.Map:
idx := strings.Index(namespace, "[")
idx := strings.Index(namespace, "[") + 1
idx2 := strings.Index(namespace, "]")
// key, _ := strconv.Atoi(namespace[idx+1 : idx2])
endIdx := idx2
// fmt.Println("ArrayIndex:", arrIdx)
// fmt.Println("LEN:", current.Len())
// if arrIdx >= current.Len() {
// return current, kind, false
// }
// fmt.Println("END IDX:", endIdx)
// fmt.Println("L NS:", len(namespace))
// fmt.Println("NS:", namespace)
if endIdx+1 < len(namespace) {
if namespace[endIdx+1:endIdx+2] == "." {
endIdx++
}
}
// fmt.Println("KEY:", namespace[idx:idx2])
// fmt.Println("KEY NS:", namespace[endIdx+1:])
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(namespace[idx+1:idx2])), namespace[idx2+1:])
return v.getStructFieldOK(current.MapIndex(reflect.ValueOf(namespace[idx:idx2])), namespace[endIdx+1:])
}
// fmt.Println("Returning field")

@ -194,10 +194,20 @@ func ValidateValuerType(field reflect.Value) interface{} {
func TestCrossNamespaceFieldValidation(t *testing.T) {
type SliceStruct struct {
Name string
}
type MapStruct struct {
Name string
}
type Inner struct {
CreatedAt *time.Time
Slice []string
SliceStructs []*SliceStruct
Map map[string]string
MapStructs map[string]*SliceStruct
}
type Test struct {
@ -210,7 +220,9 @@ func TestCrossNamespaceFieldValidation(t *testing.T) {
inner := &Inner{
CreatedAt: &now,
Slice: []string{"val1", "val2", "val3"},
SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}},
Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
}
test := &Test{
@ -232,6 +244,9 @@ func TestCrossNamespaceFieldValidation(t *testing.T) {
Equal(t, kind, reflect.String)
Equal(t, current.String(), "val2")
current, kind, ok = validate.getStructFieldOK(val, "Inner.CrazyNonExistantField")
Equal(t, ok, false)
current, kind, ok = validate.getStructFieldOK(val, "Inner.Slice[101]")
Equal(t, ok, false)
@ -240,9 +255,10 @@ func TestCrossNamespaceFieldValidation(t *testing.T) {
Equal(t, kind, reflect.String)
Equal(t, current.String(), "val3")
// fmt.Println(ok)
// fmt.Println(current)
// fmt.Println(kind)
current, kind, ok = validate.getStructFieldOK(val, "Inner.MapStructs[key2].Name")
Equal(t, ok, true)
Equal(t, kind, reflect.String)
Equal(t, current.String(), "name2")
}
func TestExistsValidation(t *testing.T) {

Loading…
Cancel
Save