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