diff options
Diffstat (limited to 'vendor/github.com/kr/logfmt/decode.go')
-rw-r--r-- | vendor/github.com/kr/logfmt/decode.go | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/vendor/github.com/kr/logfmt/decode.go b/vendor/github.com/kr/logfmt/decode.go deleted file mode 100644 index 1397fb7..0000000 --- a/vendor/github.com/kr/logfmt/decode.go +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | // Package implements the decoding of logfmt key-value pairs. | ||
2 | // | ||
3 | // Example logfmt message: | ||
4 | // | ||
5 | // foo=bar a=14 baz="hello kitty" cool%story=bro f %^asdf | ||
6 | // | ||
7 | // Example result in JSON: | ||
8 | // | ||
9 | // { "foo": "bar", "a": 14, "baz": "hello kitty", "cool%story": "bro", "f": true, "%^asdf": true } | ||
10 | // | ||
11 | // EBNFish: | ||
12 | // | ||
13 | // ident_byte = any byte greater than ' ', excluding '=' and '"' | ||
14 | // string_byte = any byte excluding '"' and '\' | ||
15 | // garbage = !ident_byte | ||
16 | // ident = ident_byte, { ident byte } | ||
17 | // key = ident | ||
18 | // value = ident | '"', { string_byte | '\', '"' }, '"' | ||
19 | // pair = key, '=', value | key, '=' | key | ||
20 | // message = { garbage, pair }, garbage | ||
21 | package logfmt | ||
22 | |||
23 | import ( | ||
24 | "reflect" | ||
25 | "strconv" | ||
26 | "strings" | ||
27 | "time" | ||
28 | ) | ||
29 | |||
30 | // Handler is the interface implemented by objects that accept logfmt | ||
31 | // key-value pairs. HandleLogfmt must copy the logfmt data if it | ||
32 | // wishes to retain the data after returning. | ||
33 | type Handler interface { | ||
34 | HandleLogfmt(key, val []byte) error | ||
35 | } | ||
36 | |||
37 | // The HandlerFunc type is an adapter to allow the use of ordinary functions as | ||
38 | // logfmt handlers. If f is a function with the appropriate signature, | ||
39 | // HandlerFunc(f) is a Handler object that calls f. | ||
40 | type HandlerFunc func(key, val []byte) error | ||
41 | |||
42 | func (f HandlerFunc) HandleLogfmt(key, val []byte) error { | ||
43 | return f(key, val) | ||
44 | } | ||
45 | |||
46 | // Unmarshal parses the logfmt encoding data and stores the result in the value | ||
47 | // pointed to by v. If v is an Handler, HandleLogfmt will be called for each | ||
48 | // key-value pair. | ||
49 | // | ||
50 | // If v is not a Handler, it will pass v to NewStructHandler and use the | ||
51 | // returned StructHandler for decoding. | ||
52 | func Unmarshal(data []byte, v interface{}) (err error) { | ||
53 | h, ok := v.(Handler) | ||
54 | if !ok { | ||
55 | h, err = NewStructHandler(v) | ||
56 | if err != nil { | ||
57 | return err | ||
58 | } | ||
59 | } | ||
60 | return gotoScanner(data, h) | ||
61 | } | ||
62 | |||
63 | // StructHandler unmarshals logfmt into a struct. It matches incoming keys to | ||
64 | // the the struct's fields (either the struct field name or its tag, preferring | ||
65 | // an exact match but also accepting a case-insensitive match. | ||
66 | // | ||
67 | // Field types supported by StructHandler are: | ||
68 | // | ||
69 | // all numeric types (e.g. float32, int, etc.) | ||
70 | // []byte | ||
71 | // string | ||
72 | // bool - true if key is present, false otherwise (the value is ignored). | ||
73 | // time.Duration - uses time.ParseDuration | ||
74 | // | ||
75 | // If a field is a pointer to an above type, and a matching key is not present | ||
76 | // in the logfmt data, the pointer will be untouched. | ||
77 | // | ||
78 | // If v is not a pointer to an Handler or struct, Unmarshal will return an | ||
79 | // error. | ||
80 | type StructHandler struct { | ||
81 | rv reflect.Value | ||
82 | } | ||
83 | |||
84 | func NewStructHandler(v interface{}) (Handler, error) { | ||
85 | rv := reflect.ValueOf(v) | ||
86 | if rv.Kind() != reflect.Ptr || rv.IsNil() { | ||
87 | return nil, &InvalidUnmarshalError{reflect.TypeOf(v)} | ||
88 | } | ||
89 | return &StructHandler{rv: rv}, nil | ||
90 | } | ||
91 | |||
92 | func (h *StructHandler) HandleLogfmt(key, val []byte) error { | ||
93 | el := h.rv.Elem() | ||
94 | skey := string(key) | ||
95 | for i := 0; i < el.NumField(); i++ { | ||
96 | fv := el.Field(i) | ||
97 | ft := el.Type().Field(i) | ||
98 | switch { | ||
99 | case ft.Name == skey: | ||
100 | case ft.Tag.Get("logfmt") == skey: | ||
101 | case strings.EqualFold(ft.Name, skey): | ||
102 | default: | ||
103 | continue | ||
104 | } | ||
105 | if fv.Kind() == reflect.Ptr { | ||
106 | if fv.IsNil() { | ||
107 | t := fv.Type().Elem() | ||
108 | v := reflect.New(t) | ||
109 | fv.Set(v) | ||
110 | fv = v | ||
111 | } | ||
112 | fv = fv.Elem() | ||
113 | } | ||
114 | switch fv.Interface().(type) { | ||
115 | case time.Duration: | ||
116 | d, err := time.ParseDuration(string(val)) | ||
117 | if err != nil { | ||
118 | return &UnmarshalTypeError{string(val), fv.Type()} | ||
119 | } | ||
120 | fv.Set(reflect.ValueOf(d)) | ||
121 | case string: | ||
122 | fv.SetString(string(val)) | ||
123 | case []byte: | ||
124 | b := make([]byte, len(val)) | ||
125 | copy(b, val) | ||
126 | fv.SetBytes(b) | ||
127 | case bool: | ||
128 | fv.SetBool(true) | ||
129 | default: | ||
130 | switch { | ||
131 | case reflect.Int <= fv.Kind() && fv.Kind() <= reflect.Int64: | ||
132 | v, err := strconv.ParseInt(string(val), 10, 64) | ||
133 | if err != nil { | ||
134 | return err | ||
135 | } | ||
136 | fv.SetInt(v) | ||
137 | case reflect.Uint32 <= fv.Kind() && fv.Kind() <= reflect.Uint64: | ||
138 | v, err := strconv.ParseUint(string(val), 10, 64) | ||
139 | if err != nil { | ||
140 | return err | ||
141 | } | ||
142 | fv.SetUint(v) | ||
143 | case reflect.Float32 <= fv.Kind() && fv.Kind() <= reflect.Float64: | ||
144 | v, err := strconv.ParseFloat(string(val), 10) | ||
145 | if err != nil { | ||
146 | return err | ||
147 | } | ||
148 | fv.SetFloat(v) | ||
149 | default: | ||
150 | return &UnmarshalTypeError{string(val), fv.Type()} | ||
151 | } | ||
152 | } | ||
153 | |||
154 | } | ||
155 | return nil | ||
156 | } | ||
157 | |||
158 | // An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. | ||
159 | // (The argument to Unmarshal must be a non-nil pointer.) | ||
160 | type InvalidUnmarshalError struct { | ||
161 | Type reflect.Type | ||
162 | } | ||
163 | |||
164 | func (e *InvalidUnmarshalError) Error() string { | ||
165 | if e.Type == nil { | ||
166 | return "logfmt: Unmarshal(nil)" | ||
167 | } | ||
168 | |||
169 | if e.Type.Kind() != reflect.Ptr { | ||
170 | return "logfmt: Unmarshal(non-pointer " + e.Type.String() + ")" | ||
171 | } | ||
172 | return "logfmt: Unmarshal(nil " + e.Type.String() + ")" | ||
173 | } | ||
174 | |||
175 | // An UnmarshalTypeError describes a logfmt value that was | ||
176 | // not appropriate for a value of a specific Go type. | ||
177 | type UnmarshalTypeError struct { | ||
178 | Value string // the logfmt value | ||
179 | Type reflect.Type // type of Go value it could not be assigned to | ||
180 | } | ||
181 | |||
182 | func (e *UnmarshalTypeError) Error() string { | ||
183 | return "logfmt: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() | ||
184 | } | ||