11 // Prettify returns the string representation of a value.
12 func Prettify(i interface{}) string {
14 prettify(reflect.ValueOf(i), 0, &buf)
18 // prettify will recursively walk value v to build a textual
19 // representation of the value.
20 func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
21 for v.Kind() == reflect.Ptr {
27 strtype := v.Type().String()
28 if strtype == "time.Time" {
29 fmt.Fprintf(buf, "%s", v.Interface())
31 } else if strings.HasPrefix(strtype, "io.") {
32 buf.WriteString("<buffer>")
36 buf.WriteString("{\n")
39 for i := 0; i < v.Type().NumField(); i++ {
40 name := v.Type().Field(i).Name
42 if name[0:1] == strings.ToLower(name[0:1]) {
43 continue // ignore unexported fields
45 if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
46 continue // ignore unset fields
48 names = append(names, name)
51 for i, n := range names {
52 val := v.FieldByName(n)
53 buf.WriteString(strings.Repeat(" ", indent+2))
54 buf.WriteString(n + ": ")
55 prettify(val, indent+2, buf)
58 buf.WriteString(",\n")
62 buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
64 strtype := v.Type().String()
65 if strtype == "[]uint8" {
66 fmt.Fprintf(buf, "<binary> len %d", v.Len())
70 nl, id, id2 := "", "", ""
72 nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
74 buf.WriteString("[" + nl)
75 for i := 0; i < v.Len(); i++ {
77 prettify(v.Index(i), indent+2, buf)
80 buf.WriteString("," + nl)
84 buf.WriteString(nl + id + "]")
86 buf.WriteString("{\n")
88 for i, k := range v.MapKeys() {
89 buf.WriteString(strings.Repeat(" ", indent+2))
90 buf.WriteString(k.String() + ": ")
91 prettify(v.MapIndex(k), indent+2, buf)
94 buf.WriteString(",\n")
98 buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
101 fmt.Fprint(buf, "<invalid value>")
105 switch v.Interface().(type) {
108 case io.ReadSeeker, io.Reader:
109 format = "buffer(%p)"
111 fmt.Fprintf(buf, format, v.Interface())