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