strings.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package agollo
  2. import (
  3. "fmt"
  4. "html/template"
  5. "reflect"
  6. "strconv"
  7. )
  8. // From html/template/content.go
  9. // Copyright 2011 The Go Authors. All rights reserved.
  10. // indirectToStringerOrError returns the value, after dereferencing as many times
  11. // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
  12. // or error,
  13. func indirectToStringerOrError(a interface{}) interface{} {
  14. if a == nil {
  15. return nil
  16. }
  17. var errorType = reflect.TypeOf((*error)(nil)).Elem()
  18. var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
  19. v := reflect.ValueOf(a)
  20. for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
  21. v = v.Elem()
  22. }
  23. return v.Interface()
  24. }
  25. // ToStringE casts an interface to a string type.
  26. func ToStringE(i interface{}) (string, error) {
  27. i = indirectToStringerOrError(i)
  28. switch s := i.(type) {
  29. case string:
  30. return s, nil
  31. case bool:
  32. return strconv.FormatBool(s), nil
  33. case float64:
  34. return strconv.FormatFloat(s, 'f', -1, 64), nil
  35. case float32:
  36. return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
  37. case int:
  38. return strconv.Itoa(s), nil
  39. case int64:
  40. return strconv.FormatInt(s, 10), nil
  41. case int32:
  42. return strconv.Itoa(int(s)), nil
  43. case int16:
  44. return strconv.FormatInt(int64(s), 10), nil
  45. case int8:
  46. return strconv.FormatInt(int64(s), 10), nil
  47. case uint:
  48. return strconv.FormatInt(int64(s), 10), nil
  49. case uint64:
  50. return strconv.FormatInt(int64(s), 10), nil
  51. case uint32:
  52. return strconv.FormatInt(int64(s), 10), nil
  53. case uint16:
  54. return strconv.FormatInt(int64(s), 10), nil
  55. case uint8:
  56. return strconv.FormatInt(int64(s), 10), nil
  57. case []byte:
  58. return string(s), nil
  59. case template.HTML:
  60. return string(s), nil
  61. case template.URL:
  62. return string(s), nil
  63. case template.JS:
  64. return string(s), nil
  65. case template.CSS:
  66. return string(s), nil
  67. case template.HTMLAttr:
  68. return string(s), nil
  69. case nil:
  70. return "", nil
  71. case fmt.Stringer:
  72. return s.String(), nil
  73. case error:
  74. return s.Error(), nil
  75. default:
  76. return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
  77. }
  78. }