gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/stretchr/objx/conversions.go (about) 1 package objx 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "encoding/json" 7 "errors" 8 "net/url" 9 "strconv" 10 ) 11 12 // SignatureSeparator is the character that is used to 13 // separate the Base64 string from the security signature. 14 const SignatureSeparator = "_" 15 16 // URLValuesSliceKeySuffix is the character that is used to 17 // specify a suffic for slices parsed by URLValues. 18 // If the suffix is set to "[i]", then the index of the slice 19 // is used in place of i 20 // Ex: Suffix "[]" would have the form a[]=b&a[]=c 21 // OR Suffix "[i]" would have the form a[0]=b&a[1]=c 22 // OR Suffix "" would have the form a=b&a=c 23 var urlValuesSliceKeySuffix = "[]" 24 25 const ( 26 URLValuesSliceKeySuffixEmpty = "" 27 URLValuesSliceKeySuffixArray = "[]" 28 URLValuesSliceKeySuffixIndex = "[i]" 29 ) 30 31 // SetURLValuesSliceKeySuffix sets the character that is used to 32 // specify a suffic for slices parsed by URLValues. 33 // If the suffix is set to "[i]", then the index of the slice 34 // is used in place of i 35 // Ex: Suffix "[]" would have the form a[]=b&a[]=c 36 // OR Suffix "[i]" would have the form a[0]=b&a[1]=c 37 // OR Suffix "" would have the form a=b&a=c 38 func SetURLValuesSliceKeySuffix(s string) error { 39 if s == URLValuesSliceKeySuffixEmpty || s == URLValuesSliceKeySuffixArray || s == URLValuesSliceKeySuffixIndex { 40 urlValuesSliceKeySuffix = s 41 return nil 42 } 43 44 return errors.New("objx: Invalid URLValuesSliceKeySuffix provided.") 45 } 46 47 // JSON converts the contained object to a JSON string 48 // representation 49 func (m Map) JSON() (string, error) { 50 result, err := json.Marshal(m) 51 if err != nil { 52 err = errors.New("objx: JSON encode failed with: " + err.Error()) 53 } 54 return string(result), err 55 } 56 57 // MustJSON converts the contained object to a JSON string 58 // representation and panics if there is an error 59 func (m Map) MustJSON() string { 60 result, err := m.JSON() 61 if err != nil { 62 panic(err.Error()) 63 } 64 return result 65 } 66 67 // Base64 converts the contained object to a Base64 string 68 // representation of the JSON string representation 69 func (m Map) Base64() (string, error) { 70 var buf bytes.Buffer 71 72 jsonData, err := m.JSON() 73 if err != nil { 74 return "", err 75 } 76 77 encoder := base64.NewEncoder(base64.StdEncoding, &buf) 78 _, _ = encoder.Write([]byte(jsonData)) 79 _ = encoder.Close() 80 81 return buf.String(), nil 82 } 83 84 // MustBase64 converts the contained object to a Base64 string 85 // representation of the JSON string representation and panics 86 // if there is an error 87 func (m Map) MustBase64() string { 88 result, err := m.Base64() 89 if err != nil { 90 panic(err.Error()) 91 } 92 return result 93 } 94 95 // SignedBase64 converts the contained object to a Base64 string 96 // representation of the JSON string representation and signs it 97 // using the provided key. 98 func (m Map) SignedBase64(key string) (string, error) { 99 base64, err := m.Base64() 100 if err != nil { 101 return "", err 102 } 103 104 sig := HashWithKey(base64, key) 105 return base64 + SignatureSeparator + sig, nil 106 } 107 108 // MustSignedBase64 converts the contained object to a Base64 string 109 // representation of the JSON string representation and signs it 110 // using the provided key and panics if there is an error 111 func (m Map) MustSignedBase64(key string) string { 112 result, err := m.SignedBase64(key) 113 if err != nil { 114 panic(err.Error()) 115 } 116 return result 117 } 118 119 /* 120 URL Query 121 ------------------------------------------------ 122 */ 123 124 // URLValues creates a url.Values object from an Obj. This 125 // function requires that the wrapped object be a map[string]interface{} 126 func (m Map) URLValues() url.Values { 127 vals := make(url.Values) 128 129 m.parseURLValues(m, vals, "") 130 131 return vals 132 } 133 134 func (m Map) parseURLValues(queryMap Map, vals url.Values, key string) { 135 useSliceIndex := false 136 if urlValuesSliceKeySuffix == "[i]" { 137 useSliceIndex = true 138 } 139 140 for k, v := range queryMap { 141 val := &Value{data: v} 142 switch { 143 case val.IsObjxMap(): 144 if key == "" { 145 m.parseURLValues(val.ObjxMap(), vals, k) 146 } else { 147 m.parseURLValues(val.ObjxMap(), vals, key+"["+k+"]") 148 } 149 case val.IsObjxMapSlice(): 150 sliceKey := k 151 if key != "" { 152 sliceKey = key + "[" + k + "]" 153 } 154 155 if useSliceIndex { 156 for i, sv := range val.MustObjxMapSlice() { 157 sk := sliceKey + "[" + strconv.FormatInt(int64(i), 10) + "]" 158 m.parseURLValues(sv, vals, sk) 159 } 160 } else { 161 sliceKey = sliceKey + urlValuesSliceKeySuffix 162 for _, sv := range val.MustObjxMapSlice() { 163 m.parseURLValues(sv, vals, sliceKey) 164 } 165 } 166 case val.IsMSISlice(): 167 sliceKey := k 168 if key != "" { 169 sliceKey = key + "[" + k + "]" 170 } 171 172 if useSliceIndex { 173 for i, sv := range val.MustMSISlice() { 174 sk := sliceKey + "[" + strconv.FormatInt(int64(i), 10) + "]" 175 m.parseURLValues(New(sv), vals, sk) 176 } 177 } else { 178 sliceKey = sliceKey + urlValuesSliceKeySuffix 179 for _, sv := range val.MustMSISlice() { 180 m.parseURLValues(New(sv), vals, sliceKey) 181 } 182 } 183 case val.IsStrSlice(), val.IsBoolSlice(), 184 val.IsFloat32Slice(), val.IsFloat64Slice(), 185 val.IsIntSlice(), val.IsInt8Slice(), val.IsInt16Slice(), val.IsInt32Slice(), val.IsInt64Slice(), 186 val.IsUintSlice(), val.IsUint8Slice(), val.IsUint16Slice(), val.IsUint32Slice(), val.IsUint64Slice(): 187 188 sliceKey := k 189 if key != "" { 190 sliceKey = key + "[" + k + "]" 191 } 192 193 if useSliceIndex { 194 for i, sv := range val.StringSlice() { 195 sk := sliceKey + "[" + strconv.FormatInt(int64(i), 10) + "]" 196 vals.Set(sk, sv) 197 } 198 } else { 199 sliceKey = sliceKey + urlValuesSliceKeySuffix 200 vals[sliceKey] = val.StringSlice() 201 } 202 203 default: 204 if key == "" { 205 vals.Set(k, val.String()) 206 } else { 207 vals.Set(key+"["+k+"]", val.String()) 208 } 209 } 210 } 211 } 212 213 // URLQuery gets an encoded URL query representing the given 214 // Obj. This function requires that the wrapped object be a 215 // map[string]interface{} 216 func (m Map) URLQuery() (string, error) { 217 return m.URLValues().Encode(), nil 218 }