uri.go (2573B)
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 }