@@ -13,13 +13,29 @@ import (
13
13
// Map represents an ordered map of fields.
14
14
type Map []Field
15
15
16
+ // SlogValue implements Value.
17
+ func (m Map ) SlogValue () interface {} {
18
+ return ForceJSON (m )
19
+ }
20
+
16
21
var _ json.Marshaler = Map (nil )
17
22
18
23
// MarshalJSON implements json.Marshaler.
19
24
//
20
25
// It is guaranteed to return a nil error.
21
- // Any error marshalling a field will
22
- // become the field's value.
26
+ // Any error marshalling a field will become the field's value.
27
+ //
28
+ // Every field value is encoded with the following process:
29
+ //
30
+ // 1. slog.Value is handled to allow any type to replace its representation for logging.
31
+ //
32
+ // 2. xerrors.Formatter is handled.
33
+ //
34
+ // 3. error and fmt.Stringer are handled.
35
+ //
36
+ // 4. slices and arrays are handled to go through the encode function for every value.
37
+ //
38
+ // 5. json.Marshal is invoked as the default case.
23
39
func (m Map ) MarshalJSON () ([]byte , error ) {
24
40
b := & bytes.Buffer {}
25
41
b .WriteByte ('{' )
@@ -55,14 +71,14 @@ func (v jsonVal) MarshalJSON() ([]byte, error) {
55
71
return json .Marshal (v .v )
56
72
}
57
73
58
- func marshalArray ( a [] interface {} ) []byte {
74
+ func marshalList ( rv reflect. Value ) []byte {
59
75
b := & bytes.Buffer {}
60
76
b .WriteByte ('[' )
61
- for i , v := range a {
77
+ for i := 0 ; i < rv . Len (); i ++ {
62
78
b .WriteByte ('\n' )
63
- b .Write (encode (v ))
79
+ b .Write (encode (rv . Index ( i ). Interface () ))
64
80
65
- if i < len ( a )- 1 {
81
+ if i < rv . Len ( )- 1 {
66
82
b .WriteByte (',' )
67
83
}
68
84
}
@@ -75,13 +91,24 @@ func encode(v interface{}) []byte {
75
91
switch v := v .(type ) {
76
92
case Value :
77
93
return encode (v .SlogValue ())
78
- case []interface {}:
79
- return marshalArray (v )
80
94
case xerrors.Formatter :
81
95
return encode (errorChain (v ))
82
96
case error , fmt.Stringer :
83
97
return encode (fmt .Sprint (v ))
84
98
default :
99
+ rv := reflect .Indirect (reflect .ValueOf (v ))
100
+ if rv .IsValid () {
101
+ switch rv .Type ().Kind () {
102
+ case reflect .Slice :
103
+ if rv .IsNil () {
104
+ break
105
+ }
106
+ fallthrough
107
+ case reflect .Array :
108
+ return marshalList (rv )
109
+ }
110
+ }
111
+
85
112
b , err := json .Marshal (v )
86
113
if err != nil {
87
114
return encode (M (
0 commit comments