-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathjson.go
141 lines (132 loc) · 4.86 KB
/
json.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package gonfig
import (
"encoding/json"
"io"
"io/ioutil"
"path"
"strings"
)
// Gonfig implementation
// Implements the Gonfig interface
type JsonGonfig struct {
obj map[string]interface{}
}
// FromJson reads the contents from the supplied reader.
// The content is parsed as json into a map[string]interface{}.
// It returns a JsonGonfig struct pointer and any error encountered
func FromJson(reader io.Reader) (Gonfig, error) {
jsonBytes, err := ioutil.ReadAll(reader)
if err != nil {
return nil, err
}
var obj map[string]interface{}
if err := json.Unmarshal(jsonBytes, &obj); err != nil {
return nil, err
}
return &JsonGonfig{obj}, nil
}
// GetString uses Get to fetch the value behind the supplied key.
// It returns a string with either the retreived value or the default value and any error encountered.
// If value is not a string it returns a UnexpectedValueTypeError
func (jgonfig *JsonGonfig) GetString(key string, defaultValue interface{}) (string, error) {
configValue, err := jgonfig.Get(key, defaultValue)
if err != nil {
return "", err
}
if stringValue, ok := configValue.(string); ok {
return stringValue, nil
} else {
return "", &UnexpectedValueTypeError{key: key, value: configValue, message: "value is not a string"}
}
}
// GetInt uses Get to fetch the value behind the supplied key.
// It returns a int with either the retreived value or the default value and any error encountered.
// If value is not a int it returns a UnexpectedValueTypeError
func (jgonfig *JsonGonfig) GetInt(key string, defaultValue interface{}) (int, error) {
value, err := jgonfig.GetFloat(key, defaultValue)
if err != nil {
return -1, err
}
return int(value), nil
}
// GetFloat uses Get to fetch the value behind the supplied key.
// It returns a float with either the retreived value or the default value and any error encountered.
// It returns a bool with either the retreived value or the default value and any error encountered.
// If value is not a float it returns a UnexpectedValueTypeError
func (jgonfig *JsonGonfig) GetFloat(key string, defaultValue interface{}) (float64, error) {
configValue, err := jgonfig.Get(key, defaultValue)
if err != nil {
return -1.0, err
}
if floatValue, ok := configValue.(float64); ok {
return floatValue, nil
} else if intValue, ok := configValue.(int); ok {
return float64(intValue), nil
} else {
return -1.0, &UnexpectedValueTypeError{key: key, value: configValue, message: "value is not a float"}
}
}
// GetBool uses Get to fetch the value behind the supplied key.
// It returns a bool with either the retreived value or the default value and any error encountered.
// If value is not a bool it returns a UnexpectedValueTypeError
func (jgonfig *JsonGonfig) GetBool(key string, defaultValue interface{}) (bool, error) {
configValue, err := jgonfig.Get(key, defaultValue)
if err != nil {
return false, err
}
if boolValue, ok := configValue.(bool); ok {
return boolValue, nil
} else {
return false, &UnexpectedValueTypeError{key: key, value: configValue, message: "value is not a bool"}
}
}
// GetAs uses Get to fetch the value behind the supplied key.
// The value is serialized into json and deserialized into the supplied target interface.
// It returns any error encountered.
func (jgonfig *JsonGonfig) GetAs(key string, target interface{}) error {
configValue, err := jgonfig.Get(key, nil)
if err != nil {
return err
}
jsonBytes, err := json.Marshal(configValue)
if err != nil {
return err
}
if err := json.Unmarshal(jsonBytes, target); err != nil {
return err
}
return nil
}
// Get attempts to retreive the value behind the supplied key.
// It returns a interface{} with either the retreived value or the default value and any error encountered.
// If supplied key is not found and defaultValue is set to nil it returns a KeyNotFoundError
// If supplied key path goes deeper into a non-map type (string, int, bool) it returns a UnexpectedValueTypeError
func (jgonfig *JsonGonfig) Get(key string, defaultValue interface{}) (interface{}, error) {
parts := strings.Split(key, "/")
var tmp interface{} = jgonfig.obj
for index, part := range parts {
if len(part) == 0 {
continue
}
if confMap, ok := tmp.(map[string]interface{}); ok {
if value, exists := confMap[part]; exists {
tmp = value
} else if defaultValue != nil {
return defaultValue, nil
} else {
return nil, &KeyNotFoundError{key: path.Join(append(parts[:index], part)...)}
}
} else if confMap, ok := tmp.(map[interface{}]interface{}); ok {
if value, exists := confMap[part]; exists {
tmp = value
} else if defaultValue != nil {
return defaultValue, nil
} else {
return nil, &KeyNotFoundError{key: path.Join(append(parts[:index], part)...)}
}
} else {
return nil, &UnexpectedValueTypeError{key: path.Join(parts[:index]...), value: tmp, message: "value behind key is not a map[string]interface{}"}
}
}
return tmp, nil
}