uri.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package httpbinding
  2. import (
  3. "math"
  4. "math/big"
  5. "strconv"
  6. "strings"
  7. )
  8. // URIValue is used to encode named URI parameters
  9. type URIValue struct {
  10. path, rawPath, buffer *[]byte
  11. key string
  12. }
  13. func newURIValue(path *[]byte, rawPath *[]byte, buffer *[]byte, key string) URIValue {
  14. return URIValue{path: path, rawPath: rawPath, buffer: buffer, key: key}
  15. }
  16. func (u URIValue) modifyURI(value string) (err error) {
  17. *u.path, *u.buffer, err = replacePathElement(*u.path, *u.buffer, u.key, value, false)
  18. if err != nil {
  19. return err
  20. }
  21. *u.rawPath, *u.buffer, err = replacePathElement(*u.rawPath, *u.buffer, u.key, value, true)
  22. return err
  23. }
  24. // Boolean encodes v as a URI string value
  25. func (u URIValue) Boolean(v bool) error {
  26. return u.modifyURI(strconv.FormatBool(v))
  27. }
  28. // String encodes v as a URI string value
  29. func (u URIValue) String(v string) error {
  30. return u.modifyURI(v)
  31. }
  32. // Byte encodes v as a URI string value
  33. func (u URIValue) Byte(v int8) error {
  34. return u.Long(int64(v))
  35. }
  36. // Short encodes v as a URI string value
  37. func (u URIValue) Short(v int16) error {
  38. return u.Long(int64(v))
  39. }
  40. // Integer encodes v as a URI string value
  41. func (u URIValue) Integer(v int32) error {
  42. return u.Long(int64(v))
  43. }
  44. // Long encodes v as a URI string value
  45. func (u URIValue) Long(v int64) error {
  46. return u.modifyURI(strconv.FormatInt(v, 10))
  47. }
  48. // Float encodes v as a query string value
  49. func (u URIValue) Float(v float32) error {
  50. return u.float(float64(v), 32)
  51. }
  52. // Double encodes v as a query string value
  53. func (u URIValue) Double(v float64) error {
  54. return u.float(v, 64)
  55. }
  56. func (u URIValue) float(v float64, bitSize int) error {
  57. switch {
  58. case math.IsNaN(v):
  59. return u.String(floatNaN)
  60. case math.IsInf(v, 1):
  61. return u.String(floatInfinity)
  62. case math.IsInf(v, -1):
  63. return u.String(floatNegInfinity)
  64. default:
  65. return u.modifyURI(strconv.FormatFloat(v, 'f', -1, bitSize))
  66. }
  67. }
  68. // BigInteger encodes v as a query string value
  69. func (u URIValue) BigInteger(v *big.Int) error {
  70. return u.modifyURI(v.String())
  71. }
  72. // BigDecimal encodes v as a query string value
  73. func (u URIValue) BigDecimal(v *big.Float) error {
  74. if i, accuracy := v.Int64(); accuracy == big.Exact {
  75. return u.Long(i)
  76. }
  77. return u.modifyURI(v.Text('e', -1))
  78. }
  79. // SplitURI parses a Smithy HTTP binding trait URI
  80. func SplitURI(uri string) (path, query string) {
  81. queryStart := strings.IndexRune(uri, '?')
  82. if queryStart == -1 {
  83. path = uri
  84. return path, query
  85. }
  86. path = uri[:queryStart]
  87. if queryStart+1 >= len(uri) {
  88. return path, query
  89. }
  90. query = uri[queryStart+1:]
  91. return path, query
  92. }