...
1 package awsutil
2
3 import (
4 "bytes"
5 "fmt"
6 "io"
7 "reflect"
8 "strings"
9 )
10
11
12 func Prettify(i interface{}) string {
13 var buf bytes.Buffer
14 prettify(reflect.ValueOf(i), 0, &buf)
15 return buf.String()
16 }
17
18
19
20 func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
21 isPtr := false
22 for v.Kind() == reflect.Ptr {
23 isPtr = true
24 v = v.Elem()
25 }
26
27 switch v.Kind() {
28 case reflect.Struct:
29 strtype := v.Type().String()
30 if strtype == "time.Time" {
31 fmt.Fprintf(buf, "%s", v.Interface())
32 break
33 } else if strings.HasPrefix(strtype, "io.") {
34 buf.WriteString("<buffer>")
35 break
36 }
37
38 if isPtr {
39 buf.WriteRune('&')
40 }
41 buf.WriteString("{\n")
42
43 names := []string{}
44 for i := 0; i < v.Type().NumField(); i++ {
45 name := v.Type().Field(i).Name
46 f := v.Field(i)
47 if name[0:1] == strings.ToLower(name[0:1]) {
48 continue
49 }
50 if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
51 continue
52 }
53 names = append(names, name)
54 }
55
56 for i, n := range names {
57 val := v.FieldByName(n)
58 buf.WriteString(strings.Repeat(" ", indent+2))
59 buf.WriteString(n + ": ")
60 prettify(val, indent+2, buf)
61
62 if i < len(names)-1 {
63 buf.WriteString(",\n")
64 }
65 }
66
67 buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
68 case reflect.Slice:
69 strtype := v.Type().String()
70 if strtype == "[]uint8" {
71 fmt.Fprintf(buf, "<binary> len %d", v.Len())
72 break
73 }
74
75 nl, id, id2 := "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
76 if isPtr {
77 buf.WriteRune('&')
78 }
79 buf.WriteString("[" + nl)
80 for i := 0; i < v.Len(); i++ {
81 buf.WriteString(id2)
82 prettify(v.Index(i), indent+2, buf)
83
84 if i < v.Len()-1 {
85 buf.WriteString("," + nl)
86 }
87 }
88
89 buf.WriteString(nl + id + "]")
90 case reflect.Map:
91 if isPtr {
92 buf.WriteRune('&')
93 }
94 buf.WriteString("{\n")
95
96 for i, k := range v.MapKeys() {
97 buf.WriteString(strings.Repeat(" ", indent+2))
98 buf.WriteString(k.String() + ": ")
99 prettify(v.MapIndex(k), indent+2, buf)
100
101 if i < v.Len()-1 {
102 buf.WriteString(",\n")
103 }
104 }
105
106 buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
107 default:
108 if !v.IsValid() {
109 fmt.Fprint(buf, "<invalid value>")
110 return
111 }
112
113 for v.Kind() == reflect.Interface && !v.IsNil() {
114 v = v.Elem()
115 }
116
117 if v.Kind() == reflect.Ptr || v.Kind() == reflect.Struct || v.Kind() == reflect.Map || v.Kind() == reflect.Slice {
118 prettify(v, indent, buf)
119 return
120 }
121
122 format := "%v"
123 switch v.Interface().(type) {
124 case string:
125 format = "%q"
126 case io.ReadSeeker, io.Reader:
127 format = "buffer(%p)"
128 }
129 fmt.Fprintf(buf, format, v.Interface())
130 }
131 }
132
View as plain text