func traverseData()

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
}