This repository was archived by the owner on May 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathjson_source.go
More file actions
97 lines (82 loc) · 2.65 KB
/
json_source.go
File metadata and controls
97 lines (82 loc) · 2.65 KB
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
package configo
import (
"encoding/json"
"flag"
"io/ioutil"
"os"
"strconv"
)
// JSONSource houses key-value pairs unmarshaled from JSON data.
type JSONSource struct {
values map[string]interface{}
}
// FromConfigurableJSONFile allows the user to configure the config file path
// via the -config command line flag.
func FromConfigurableJSONFile() *JSONSource {
flags := flag.NewFlagSet("config-file", flag.ContinueOnError)
filename := flags.String("config", "config.json", "The path to the JSON config file.")
flags.Parse(os.Args[1:]) // don't include the command name (argument #0).
return FromJSONFile(*filename)
}
// FromJSONFile reads and unmarshals the file at the provided path into a JSONSource.
// Any resulting error results in a panic.
func FromJSONFile(filename string) *JSONSource {
if contents, err := ioutil.ReadFile(filename); err != nil {
panic(err)
} else {
return FromJSONContent(contents)
}
}
// FromConditionalJSONFile loads a required file if the provided condition returns true;
// otherwise loading the file is optional.
func FromConditionalJSONFile(filename string, condition func() bool) *JSONSource {
if condition() {
return FromJSONFile(filename)
}
return FromOptionalJSONFile(filename)
}
// FromOptionalJSONFile is like FromJSONFile but it does not panic if the file is not found.
func FromOptionalJSONFile(filename string) *JSONSource {
if contents, _ := ioutil.ReadFile(filename); len(contents) > 0 {
return FromJSONContent(contents)
}
return nil
}
// FromJSONContent unmarshals the provided json content into a JSONSource.
// Any resulting error results in a panic.
func FromJSONContent(raw []byte) *JSONSource {
values := make(map[string]interface{})
if err := json.Unmarshal(raw, &values); err != nil {
panic("json error: " + err.Error())
}
return FromJSONObject(values)
}
func FromJSONObject(values map[string]interface{}) *JSONSource {
return &JSONSource{values: values}
}
func (this *JSONSource) Strings(key string) ([]string, error) {
// FUTURE: if contents of key contain a hyphen, change it to an underscore?
// FUTURE: split on / character to indicate another level
if item, found := this.values[key]; found {
return toStrings(item), nil
}
return nil, ErrKeyNotFound
}
func toStrings(value interface{}) (values []string) {
switch typed := value.(type) {
case string:
return []string{typed}
case float64:
return []string{strconv.FormatFloat(typed, 'f', -1, 64)}
case bool:
return []string{strconv.FormatBool(typed)}
case []interface{}:
for _, item := range typed {
values = append(values, convertToString(item))
}
return values
default:
return nil
}
}
func (this *JSONSource) Initialize() {}