nullify.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // Package nullify provides methods to init nil values structs for test assertion.
  2. package nullify
  3. import (
  4. "reflect"
  5. "unsafe"
  6. sdk "github.com/cosmos/cosmos-sdk/types"
  7. )
  8. var (
  9. coinType = reflect.TypeOf(sdk.Coin{})
  10. coinsType = reflect.TypeOf(sdk.Coins{})
  11. )
  12. // Fill analyze all struct fields and slices with
  13. // reflection and initialize the nil and empty slices,
  14. // structs, and pointers.
  15. func Fill(x interface{}) interface{} {
  16. v := reflect.Indirect(reflect.ValueOf(x))
  17. switch v.Kind() {
  18. case reflect.Slice:
  19. for i := 0; i < v.Len(); i++ {
  20. obj := v.Index(i)
  21. objPt := reflect.NewAt(obj.Type(), unsafe.Pointer(obj.UnsafeAddr())).Interface()
  22. objPt = Fill(objPt)
  23. obj.Set(reflect.ValueOf(objPt))
  24. }
  25. case reflect.Struct:
  26. for i := 0; i < v.NumField(); i++ {
  27. f := reflect.Indirect(v.Field(i))
  28. if !f.CanSet() {
  29. continue
  30. }
  31. switch f.Kind() {
  32. case reflect.Slice:
  33. f.Set(reflect.MakeSlice(f.Type(), 0, 0))
  34. case reflect.Struct:
  35. switch f.Type() {
  36. case coinType:
  37. coin := reflect.New(coinType).Interface()
  38. s := reflect.ValueOf(coin).Elem()
  39. f.Set(s)
  40. case coinsType:
  41. coins := reflect.New(coinsType).Interface()
  42. s := reflect.ValueOf(coins).Elem()
  43. f.Set(s)
  44. default:
  45. objPt := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Interface()
  46. s := Fill(objPt)
  47. f.Set(reflect.ValueOf(s))
  48. }
  49. }
  50. }
  51. }
  52. return reflect.Indirect(v).Interface()
  53. }