| 11 | } |
| 12 | |
| 13 | func dump(v reflect.Value, ident string) string { |
| 14 | if !v.IsValid() { |
| 15 | return "nil" |
| 16 | } |
| 17 | t := v.Type() |
| 18 | switch t.Kind() { |
| 19 | case reflect.Struct: |
| 20 | out := t.Name() + "{\n" |
| 21 | for i := 0; i < t.NumField(); i++ { |
| 22 | f := t.Field(i) |
| 23 | if isPrivate(f.Name) { |
| 24 | continue |
| 25 | } |
| 26 | s := v.Field(i) |
| 27 | out += fmt.Sprintf("%v%v: %v,\n", ident+"\t", f.Name, dump(s, ident+"\t")) |
| 28 | } |
| 29 | return out + ident + "}" |
| 30 | case reflect.Slice: |
| 31 | if v.Len() == 0 { |
| 32 | return t.String() + "{}" |
| 33 | } |
| 34 | out := t.String() + "{\n" |
| 35 | for i := 0; i < v.Len(); i++ { |
| 36 | s := v.Index(i) |
| 37 | out += fmt.Sprintf("%v%v,", ident+"\t", dump(s, ident+"\t")) |
| 38 | if i+1 < v.Len() { |
| 39 | out += "\n" |
| 40 | } |
| 41 | } |
| 42 | return out + "\n" + ident + "}" |
| 43 | case reflect.Ptr: |
| 44 | return dump(v.Elem(), ident) |
| 45 | case reflect.Interface: |
| 46 | return dump(reflect.ValueOf(v.Interface()), ident) |
| 47 | |
| 48 | case reflect.String: |
| 49 | return fmt.Sprintf("%q", v) |
| 50 | default: |
| 51 | return fmt.Sprintf("%v", v) |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | var isCapital = regexp.MustCompile("^[A-Z]") |
| 56 | |