...
1 package ff
2
3 import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "strconv"
8 )
9
10
11
12
13
14 func JSONParser(r io.Reader, set func(name, value string) error) error {
15 var m map[string]interface{}
16 d := json.NewDecoder(r)
17 d.UseNumber()
18 if err := d.Decode(&m); err != nil {
19 return JSONParseError{Inner: err}
20 }
21 for key, val := range m {
22 values, err := stringifySlice(val)
23 if err != nil {
24 return JSONParseError{Inner: err}
25 }
26 for _, value := range values {
27 if err := set(key, value); err != nil {
28 return err
29 }
30 }
31 }
32 return nil
33 }
34
35 func stringifySlice(val interface{}) ([]string, error) {
36 if vals, ok := val.([]interface{}); ok {
37 ss := make([]string, len(vals))
38 for i := range vals {
39 s, err := stringifyValue(vals[i])
40 if err != nil {
41 return nil, err
42 }
43 ss[i] = s
44 }
45 return ss, nil
46 }
47 s, err := stringifyValue(val)
48 if err != nil {
49 return nil, err
50 }
51 return []string{s}, nil
52 }
53
54 func stringifyValue(val interface{}) (string, error) {
55 switch v := val.(type) {
56 case string:
57 return v, nil
58 case json.Number:
59 return v.String(), nil
60 case bool:
61 return strconv.FormatBool(v), nil
62 default:
63 return "", StringConversionError{Value: val}
64 }
65 }
66
67
68 type JSONParseError struct {
69 Inner error
70 }
71
72
73 func (e JSONParseError) Error() string {
74 return fmt.Sprintf("error parsing JSON config: %v", e.Inner)
75 }
76
77
78
79 func (e JSONParseError) Unwrap() error {
80 return e.Inner
81 }
82
83
84
85 type StringConversionError struct {
86 Value interface{}
87 }
88
89
90 func (e StringConversionError) Error() string {
91 return fmt.Sprintf("couldn't convert %q (type %T) to string", e.Value, e.Value)
92 }
93
View as plain text