1 package zerolog
2
3 import (
4 "encoding/json"
5 "net"
6 "sort"
7 "time"
8 "unsafe"
9 )
10
11 func isNilValue(i interface{}) bool {
12 return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0
13 }
14
15 func appendFields(dst []byte, fields interface{}) []byte {
16 switch fields := fields.(type) {
17 case []interface{}:
18 if n := len(fields); n&0x1 == 1 {
19 fields = fields[:n-1]
20 }
21 dst = appendFieldList(dst, fields)
22 case map[string]interface{}:
23 keys := make([]string, 0, len(fields))
24 for key := range fields {
25 keys = append(keys, key)
26 }
27 sort.Strings(keys)
28 kv := make([]interface{}, 2)
29 for _, key := range keys {
30 kv[0], kv[1] = key, fields[key]
31 dst = appendFieldList(dst, kv)
32 }
33 }
34 return dst
35 }
36
37 func appendFieldList(dst []byte, kvList []interface{}) []byte {
38 for i, n := 0, len(kvList); i < n; i += 2 {
39 key, val := kvList[i], kvList[i+1]
40 if key, ok := key.(string); ok {
41 dst = enc.AppendKey(dst, key)
42 } else {
43 continue
44 }
45 if val, ok := val.(LogObjectMarshaler); ok {
46 e := newEvent(nil, 0)
47 e.buf = e.buf[:0]
48 e.appendObject(val)
49 dst = append(dst, e.buf...)
50 putEvent(e)
51 continue
52 }
53 switch val := val.(type) {
54 case string:
55 dst = enc.AppendString(dst, val)
56 case []byte:
57 dst = enc.AppendBytes(dst, val)
58 case error:
59 switch m := ErrorMarshalFunc(val).(type) {
60 case LogObjectMarshaler:
61 e := newEvent(nil, 0)
62 e.buf = e.buf[:0]
63 e.appendObject(m)
64 dst = append(dst, e.buf...)
65 putEvent(e)
66 case error:
67 if m == nil || isNilValue(m) {
68 dst = enc.AppendNil(dst)
69 } else {
70 dst = enc.AppendString(dst, m.Error())
71 }
72 case string:
73 dst = enc.AppendString(dst, m)
74 default:
75 dst = enc.AppendInterface(dst, m)
76 }
77 case []error:
78 dst = enc.AppendArrayStart(dst)
79 for i, err := range val {
80 switch m := ErrorMarshalFunc(err).(type) {
81 case LogObjectMarshaler:
82 e := newEvent(nil, 0)
83 e.buf = e.buf[:0]
84 e.appendObject(m)
85 dst = append(dst, e.buf...)
86 putEvent(e)
87 case error:
88 if m == nil || isNilValue(m) {
89 dst = enc.AppendNil(dst)
90 } else {
91 dst = enc.AppendString(dst, m.Error())
92 }
93 case string:
94 dst = enc.AppendString(dst, m)
95 default:
96 dst = enc.AppendInterface(dst, m)
97 }
98
99 if i < (len(val) - 1) {
100 enc.AppendArrayDelim(dst)
101 }
102 }
103 dst = enc.AppendArrayEnd(dst)
104 case bool:
105 dst = enc.AppendBool(dst, val)
106 case int:
107 dst = enc.AppendInt(dst, val)
108 case int8:
109 dst = enc.AppendInt8(dst, val)
110 case int16:
111 dst = enc.AppendInt16(dst, val)
112 case int32:
113 dst = enc.AppendInt32(dst, val)
114 case int64:
115 dst = enc.AppendInt64(dst, val)
116 case uint:
117 dst = enc.AppendUint(dst, val)
118 case uint8:
119 dst = enc.AppendUint8(dst, val)
120 case uint16:
121 dst = enc.AppendUint16(dst, val)
122 case uint32:
123 dst = enc.AppendUint32(dst, val)
124 case uint64:
125 dst = enc.AppendUint64(dst, val)
126 case float32:
127 dst = enc.AppendFloat32(dst, val)
128 case float64:
129 dst = enc.AppendFloat64(dst, val)
130 case time.Time:
131 dst = enc.AppendTime(dst, val, TimeFieldFormat)
132 case time.Duration:
133 dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger)
134 case *string:
135 if val != nil {
136 dst = enc.AppendString(dst, *val)
137 } else {
138 dst = enc.AppendNil(dst)
139 }
140 case *bool:
141 if val != nil {
142 dst = enc.AppendBool(dst, *val)
143 } else {
144 dst = enc.AppendNil(dst)
145 }
146 case *int:
147 if val != nil {
148 dst = enc.AppendInt(dst, *val)
149 } else {
150 dst = enc.AppendNil(dst)
151 }
152 case *int8:
153 if val != nil {
154 dst = enc.AppendInt8(dst, *val)
155 } else {
156 dst = enc.AppendNil(dst)
157 }
158 case *int16:
159 if val != nil {
160 dst = enc.AppendInt16(dst, *val)
161 } else {
162 dst = enc.AppendNil(dst)
163 }
164 case *int32:
165 if val != nil {
166 dst = enc.AppendInt32(dst, *val)
167 } else {
168 dst = enc.AppendNil(dst)
169 }
170 case *int64:
171 if val != nil {
172 dst = enc.AppendInt64(dst, *val)
173 } else {
174 dst = enc.AppendNil(dst)
175 }
176 case *uint:
177 if val != nil {
178 dst = enc.AppendUint(dst, *val)
179 } else {
180 dst = enc.AppendNil(dst)
181 }
182 case *uint8:
183 if val != nil {
184 dst = enc.AppendUint8(dst, *val)
185 } else {
186 dst = enc.AppendNil(dst)
187 }
188 case *uint16:
189 if val != nil {
190 dst = enc.AppendUint16(dst, *val)
191 } else {
192 dst = enc.AppendNil(dst)
193 }
194 case *uint32:
195 if val != nil {
196 dst = enc.AppendUint32(dst, *val)
197 } else {
198 dst = enc.AppendNil(dst)
199 }
200 case *uint64:
201 if val != nil {
202 dst = enc.AppendUint64(dst, *val)
203 } else {
204 dst = enc.AppendNil(dst)
205 }
206 case *float32:
207 if val != nil {
208 dst = enc.AppendFloat32(dst, *val)
209 } else {
210 dst = enc.AppendNil(dst)
211 }
212 case *float64:
213 if val != nil {
214 dst = enc.AppendFloat64(dst, *val)
215 } else {
216 dst = enc.AppendNil(dst)
217 }
218 case *time.Time:
219 if val != nil {
220 dst = enc.AppendTime(dst, *val, TimeFieldFormat)
221 } else {
222 dst = enc.AppendNil(dst)
223 }
224 case *time.Duration:
225 if val != nil {
226 dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger)
227 } else {
228 dst = enc.AppendNil(dst)
229 }
230 case []string:
231 dst = enc.AppendStrings(dst, val)
232 case []bool:
233 dst = enc.AppendBools(dst, val)
234 case []int:
235 dst = enc.AppendInts(dst, val)
236 case []int8:
237 dst = enc.AppendInts8(dst, val)
238 case []int16:
239 dst = enc.AppendInts16(dst, val)
240 case []int32:
241 dst = enc.AppendInts32(dst, val)
242 case []int64:
243 dst = enc.AppendInts64(dst, val)
244 case []uint:
245 dst = enc.AppendUints(dst, val)
246
247
248 case []uint16:
249 dst = enc.AppendUints16(dst, val)
250 case []uint32:
251 dst = enc.AppendUints32(dst, val)
252 case []uint64:
253 dst = enc.AppendUints64(dst, val)
254 case []float32:
255 dst = enc.AppendFloats32(dst, val)
256 case []float64:
257 dst = enc.AppendFloats64(dst, val)
258 case []time.Time:
259 dst = enc.AppendTimes(dst, val, TimeFieldFormat)
260 case []time.Duration:
261 dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger)
262 case nil:
263 dst = enc.AppendNil(dst)
264 case net.IP:
265 dst = enc.AppendIPAddr(dst, val)
266 case net.IPNet:
267 dst = enc.AppendIPPrefix(dst, val)
268 case net.HardwareAddr:
269 dst = enc.AppendMACAddr(dst, val)
270 case json.RawMessage:
271 dst = appendJSON(dst, val)
272 default:
273 dst = enc.AppendInterface(dst, val)
274 }
275 }
276 return dst
277 }
278
View as plain text