| package awsutil |
| |
| import ( |
| "bytes" |
| "fmt" |
| "io" |
| "reflect" |
| "strings" |
| ) |
| |
| // Prettify returns the string representation of a value. |
| func Prettify(i interface{}) string { |
| var buf bytes.Buffer |
| prettify(reflect.ValueOf(i), 0, &buf) |
| return buf.String() |
| } |
| |
| // prettify will recursively walk value v to build a textual |
| // representation of the value. |
| func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { |
| for v.Kind() == reflect.Ptr { |
| v = v.Elem() |
| } |
| |
| switch v.Kind() { |
| case reflect.Struct: |
| strtype := v.Type().String() |
| if strtype == "time.Time" { |
| fmt.Fprintf(buf, "%s", v.Interface()) |
| break |
| } else if strings.HasPrefix(strtype, "io.") { |
| buf.WriteString("<buffer>") |
| break |
| } |
| |
| buf.WriteString("{\n") |
| |
| names := []string{} |
| for i := 0; i < v.Type().NumField(); i++ { |
| name := v.Type().Field(i).Name |
| f := v.Field(i) |
| if name[0:1] == strings.ToLower(name[0:1]) { |
| continue // ignore unexported fields |
| } |
| if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() { |
| continue // ignore unset fields |
| } |
| names = append(names, name) |
| } |
| |
| for i, n := range names { |
| val := v.FieldByName(n) |
| buf.WriteString(strings.Repeat(" ", indent+2)) |
| buf.WriteString(n + ": ") |
| prettify(val, indent+2, buf) |
| |
| if i < len(names)-1 { |
| buf.WriteString(",\n") |
| } |
| } |
| |
| buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") |
| case reflect.Slice: |
| strtype := v.Type().String() |
| if strtype == "[]uint8" { |
| fmt.Fprintf(buf, "<binary> len %d", v.Len()) |
| break |
| } |
| |
| nl, id, id2 := "", "", "" |
| if v.Len() > 3 { |
| nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) |
| } |
| buf.WriteString("[" + nl) |
| for i := 0; i < v.Len(); i++ { |
| buf.WriteString(id2) |
| prettify(v.Index(i), indent+2, buf) |
| |
| if i < v.Len()-1 { |
| buf.WriteString("," + nl) |
| } |
| } |
| |
| buf.WriteString(nl + id + "]") |
| case reflect.Map: |
| buf.WriteString("{\n") |
| |
| for i, k := range v.MapKeys() { |
| buf.WriteString(strings.Repeat(" ", indent+2)) |
| buf.WriteString(k.String() + ": ") |
| prettify(v.MapIndex(k), indent+2, buf) |
| |
| if i < v.Len()-1 { |
| buf.WriteString(",\n") |
| } |
| } |
| |
| buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") |
| default: |
| if !v.IsValid() { |
| fmt.Fprint(buf, "<invalid value>") |
| return |
| } |
| format := "%v" |
| switch v.Interface().(type) { |
| case string: |
| format = "%q" |
| case io.ReadSeeker, io.Reader: |
| format = "buffer(%p)" |
| } |
| fmt.Fprintf(buf, format, v.Interface()) |
| } |
| } |