string_value.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package awsutil
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. )
  8. // StringValue returns the string representation of a value.
  9. func StringValue(i interface{}) string {
  10. var buf bytes.Buffer
  11. stringValue(reflect.ValueOf(i), 0, &buf)
  12. return buf.String()
  13. }
  14. func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
  15. for v.Kind() == reflect.Ptr {
  16. v = v.Elem()
  17. }
  18. switch v.Kind() {
  19. case reflect.Struct:
  20. buf.WriteString("{\n")
  21. for i := 0; i < v.Type().NumField(); i++ {
  22. ft := v.Type().Field(i)
  23. fv := v.Field(i)
  24. if ft.Name[0:1] == strings.ToLower(ft.Name[0:1]) {
  25. continue // ignore unexported fields
  26. }
  27. if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Slice) && fv.IsNil() {
  28. continue // ignore unset fields
  29. }
  30. buf.WriteString(strings.Repeat(" ", indent+2))
  31. buf.WriteString(ft.Name + ": ")
  32. if tag := ft.Tag.Get("sensitive"); tag == "true" {
  33. buf.WriteString("<sensitive>")
  34. } else {
  35. stringValue(fv, indent+2, buf)
  36. }
  37. buf.WriteString(",\n")
  38. }
  39. buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
  40. case reflect.Slice:
  41. nl, id, id2 := "", "", ""
  42. if v.Len() > 3 {
  43. nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
  44. }
  45. buf.WriteString("[" + nl)
  46. for i := 0; i < v.Len(); i++ {
  47. buf.WriteString(id2)
  48. stringValue(v.Index(i), indent+2, buf)
  49. if i < v.Len()-1 {
  50. buf.WriteString("," + nl)
  51. }
  52. }
  53. buf.WriteString(nl + id + "]")
  54. case reflect.Map:
  55. buf.WriteString("{\n")
  56. for i, k := range v.MapKeys() {
  57. buf.WriteString(strings.Repeat(" ", indent+2))
  58. buf.WriteString(k.String() + ": ")
  59. stringValue(v.MapIndex(k), indent+2, buf)
  60. if i < v.Len()-1 {
  61. buf.WriteString(",\n")
  62. }
  63. }
  64. buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
  65. default:
  66. format := "%v"
  67. switch v.Interface().(type) {
  68. case string:
  69. format = "%q"
  70. }
  71. fmt.Fprintf(buf, format, v.Interface())
  72. }
  73. }