10 // StringValue returns the string representation of a value.
11 func StringValue(i interface{}) string {
13 stringValue(reflect.ValueOf(i), 0, &buf)
17 func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
18 for v.Kind() == reflect.Ptr {
24 buf.WriteString("{\n")
26 for i := 0; i < v.Type().NumField(); i++ {
27 ft := v.Type().Field(i)
30 if ft.Name[0:1] == strings.ToLower(ft.Name[0:1]) {
31 continue // ignore unexported fields
33 if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Slice) && fv.IsNil() {
34 continue // ignore unset fields
37 buf.WriteString(strings.Repeat(" ", indent+2))
38 buf.WriteString(ft.Name + ": ")
40 if tag := ft.Tag.Get("sensitive"); tag == "true" {
41 buf.WriteString("<sensitive>")
43 stringValue(fv, indent+2, buf)
46 buf.WriteString(",\n")
49 buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
51 nl, id, id2 := "", "", ""
53 nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
55 buf.WriteString("[" + nl)
56 for i := 0; i < v.Len(); i++ {
58 stringValue(v.Index(i), indent+2, buf)
61 buf.WriteString("," + nl)
65 buf.WriteString(nl + id + "]")
67 buf.WriteString("{\n")
69 for i, k := range v.MapKeys() {
70 buf.WriteString(strings.Repeat(" ", indent+2))
71 buf.WriteString(k.String() + ": ")
72 stringValue(v.MapIndex(k), indent+2, buf)
75 buf.WriteString(",\n")
79 buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
82 switch v.Interface().(type) {
86 fmt.Fprintf(buf, format, v.Interface())