OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / stretchr / testify / vendor / github.com / stretchr / objx / map.go
1 package objx
2
3 import (
4         "encoding/base64"
5         "encoding/json"
6         "errors"
7         "io/ioutil"
8         "net/url"
9         "strings"
10 )
11
12 // MSIConvertable is an interface that defines methods for converting your
13 // custom types to a map[string]interface{} representation.
14 type MSIConvertable interface {
15         // MSI gets a map[string]interface{} (msi) representing the
16         // object.
17         MSI() map[string]interface{}
18 }
19
20 // Map provides extended functionality for working with
21 // untyped data, in particular map[string]interface (msi).
22 type Map map[string]interface{}
23
24 // Value returns the internal value instance
25 func (m Map) Value() *Value {
26         return &Value{data: m}
27 }
28
29 // Nil represents a nil Map.
30 var Nil Map = New(nil)
31
32 // New creates a new Map containing the map[string]interface{} in the data argument.
33 // If the data argument is not a map[string]interface, New attempts to call the
34 // MSI() method on the MSIConvertable interface to create one.
35 func New(data interface{}) Map {
36         if _, ok := data.(map[string]interface{}); !ok {
37                 if converter, ok := data.(MSIConvertable); ok {
38                         data = converter.MSI()
39                 } else {
40                         return nil
41                 }
42         }
43         return Map(data.(map[string]interface{}))
44 }
45
46 // MSI creates a map[string]interface{} and puts it inside a new Map.
47 //
48 // The arguments follow a key, value pattern.
49 //
50 // Panics
51 //
52 // Panics if any key arugment is non-string or if there are an odd number of arguments.
53 //
54 // Example
55 //
56 // To easily create Maps:
57 //
58 //     m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
59 //
60 //     // creates an Map equivalent to
61 //     m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
62 func MSI(keyAndValuePairs ...interface{}) Map {
63
64         newMap := make(map[string]interface{})
65         keyAndValuePairsLen := len(keyAndValuePairs)
66
67         if keyAndValuePairsLen%2 != 0 {
68                 panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
69         }
70
71         for i := 0; i < keyAndValuePairsLen; i = i + 2 {
72
73                 key := keyAndValuePairs[i]
74                 value := keyAndValuePairs[i+1]
75
76                 // make sure the key is a string
77                 keyString, keyStringOK := key.(string)
78                 if !keyStringOK {
79                         panic("objx: MSI must follow 'string, interface{}' pattern.  " + keyString + " is not a valid key.")
80                 }
81
82                 newMap[keyString] = value
83
84         }
85
86         return New(newMap)
87 }
88
89 // ****** Conversion Constructors
90
91 // MustFromJSON creates a new Map containing the data specified in the
92 // jsonString.
93 //
94 // Panics if the JSON is invalid.
95 func MustFromJSON(jsonString string) Map {
96         o, err := FromJSON(jsonString)
97
98         if err != nil {
99                 panic("objx: MustFromJSON failed with error: " + err.Error())
100         }
101
102         return o
103 }
104
105 // FromJSON creates a new Map containing the data specified in the
106 // jsonString.
107 //
108 // Returns an error if the JSON is invalid.
109 func FromJSON(jsonString string) (Map, error) {
110
111         var data interface{}
112         err := json.Unmarshal([]byte(jsonString), &data)
113
114         if err != nil {
115                 return Nil, err
116         }
117
118         return New(data), nil
119
120 }
121
122 // FromBase64 creates a new Obj containing the data specified
123 // in the Base64 string.
124 //
125 // The string is an encoded JSON string returned by Base64
126 func FromBase64(base64String string) (Map, error) {
127
128         decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
129
130         decoded, err := ioutil.ReadAll(decoder)
131         if err != nil {
132                 return nil, err
133         }
134
135         return FromJSON(string(decoded))
136 }
137
138 // MustFromBase64 creates a new Obj containing the data specified
139 // in the Base64 string and panics if there is an error.
140 //
141 // The string is an encoded JSON string returned by Base64
142 func MustFromBase64(base64String string) Map {
143
144         result, err := FromBase64(base64String)
145
146         if err != nil {
147                 panic("objx: MustFromBase64 failed with error: " + err.Error())
148         }
149
150         return result
151 }
152
153 // FromSignedBase64 creates a new Obj containing the data specified
154 // in the Base64 string.
155 //
156 // The string is an encoded JSON string returned by SignedBase64
157 func FromSignedBase64(base64String, key string) (Map, error) {
158         parts := strings.Split(base64String, SignatureSeparator)
159         if len(parts) != 2 {
160                 return nil, errors.New("objx: Signed base64 string is malformed.")
161         }
162
163         sig := HashWithKey(parts[0], key)
164         if parts[1] != sig {
165                 return nil, errors.New("objx: Signature for base64 data does not match.")
166         }
167
168         return FromBase64(parts[0])
169 }
170
171 // MustFromSignedBase64 creates a new Obj containing the data specified
172 // in the Base64 string and panics if there is an error.
173 //
174 // The string is an encoded JSON string returned by Base64
175 func MustFromSignedBase64(base64String, key string) Map {
176
177         result, err := FromSignedBase64(base64String, key)
178
179         if err != nil {
180                 panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
181         }
182
183         return result
184 }
185
186 // FromURLQuery generates a new Obj by parsing the specified
187 // query.
188 //
189 // For queries with multiple values, the first value is selected.
190 func FromURLQuery(query string) (Map, error) {
191
192         vals, err := url.ParseQuery(query)
193
194         if err != nil {
195                 return nil, err
196         }
197
198         m := make(map[string]interface{})
199         for k, vals := range vals {
200                 m[k] = vals[0]
201         }
202
203         return New(m), nil
204 }
205
206 // MustFromURLQuery generates a new Obj by parsing the specified
207 // query.
208 //
209 // For queries with multiple values, the first value is selected.
210 //
211 // Panics if it encounters an error
212 func MustFromURLQuery(query string) Map {
213
214         o, err := FromURLQuery(query)
215
216         if err != nil {
217                 panic("objx: MustFromURLQuery failed with error: " + err.Error())
218         }
219
220         return o
221
222 }