-
Notifications
You must be signed in to change notification settings - Fork 10
/
parse.go
51 lines (44 loc) · 1.28 KB
/
parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package initdata
import (
"encoding/json"
"fmt"
"net/url"
"strings"
)
var (
// List of properties which should always be interpreted as strings.
_stringProps = map[string]bool{
"start_param": true,
}
)
// Parse converts passed init data presented as query string to InitData
// object.
func Parse(initData string) (InitData, error) {
// Parse passed init data as query string.
q, err := url.ParseQuery(initData)
if err != nil {
return InitData{}, ErrUnexpectedFormat
}
// According to documentation, we could only meet such types as int64,
// string, or another object. So, we create
pairs := make([]string, 0, len(q))
for k, v := range q {
// Derive real value. We know that there can not be any arrays and value
// can be the only one.
val := v[0]
valFormat := "%q:%q"
// If passed value is valid in the context of JSON, it means, we could
// insert this value without formatting.
if isString := _stringProps[k]; !isString && json.Valid([]byte(val)) {
valFormat = "%q:%s"
}
pairs = append(pairs, fmt.Sprintf(valFormat, k, val))
}
// Unmarshal JSON to our custom structure.
var d InitData
jStr := fmt.Sprintf("{%s}", strings.Join(pairs, ","))
if err := json.Unmarshal([]byte(jStr), &d); err != nil {
return InitData{}, ErrUnexpectedFormat
}
return d, nil
}