in common.go [198:264]
func traverseData(v reflect.Value, f func(reflect.Value) DError, actions ...func(reflect.Value) traverseAction) DError {
if !v.CanSet() {
// Don't run on private fields.
return nil
}
for _, action := range actions {
switch action(v) {
case prune:
return nil
}
}
switch v.Kind() {
case reflect.Chan, reflect.Func:
return nil
case reflect.Interface, reflect.Ptr, reflect.UnsafePointer:
if v.IsNil() {
return nil
}
// I'm a pointer, dereference me.
return traverseData(v.Elem(), f, actions...)
}
switch v.Kind() {
case reflect.Array, reflect.Slice:
for i := 0; i < v.Len(); i++ {
if err := traverseData(v.Index(i), f, actions...); err != nil {
return err
}
}
case reflect.Map:
kvs := v.MapKeys()
for _, kv := range kvs {
vv := v.MapIndex(kv)
// Create new mutable copies of the key and value.
// Modify the copies.
newKv := reflect.New(kv.Type()).Elem()
newKv.Set(kv)
newVv := reflect.New(vv.Type()).Elem()
newVv.Set(vv)
if err := traverseData(newKv, f, actions...); err != nil {
return err
}
if err := traverseData(newVv, f, actions...); err != nil {
return err
}
// Delete the old key-value.
v.SetMapIndex(kv, reflect.Value{})
// Set the new key-value.
v.SetMapIndex(newKv, newVv)
}
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
if err := traverseData(v.Field(i), f, actions...); err != nil {
return err
}
}
default:
// As far as I can tell, this is a basic data type. Run f on it.
return f(v)
}
return nil
}