Repository: uber-go/zap
File: zapcore/memory_encoder.go (Go)

Code before:

// MapObjectEncoder is an ObjectEncoder backed by a simple
// map[string]interface{}. It's not fast enough for production use, but it's
// helpful in tests.
type MapObjectEncoder struct {
	// Fields contains the entire encoded log context.
	Fields map[string]interface{}
	// cur is a pointer to the namespace we're currently writing to.
	cur map[string]interface{}
}

// NewMapObjectEncoder creates a new map-backed ObjectEncoder.
func NewMapObjectEncoder() *MapObjectEncoder {
	m := make(map[string]interface{})
	return &MapObjectEncoder{
		Fields: m,
		cur:    m,
	}
}

// AddArray implements ObjectEncoder.
func (m *MapObjectEncoder) AddArray(key string, v ArrayMarshaler) error {
	arr := &sliceArrayEncoder{}
	err := v.MarshalLogArray(arr)
	if arr.elems == nil {
		arr.elems = []interface{}{}
	}
	m.cur[key] = arr.elems
	return err
}

// AddObject implements ObjectEncoder.
func (m *MapObjectEncoder) AddObject(k string, v ObjectMarshaler) error {
	newMap := NewMapObjectEncoder()
	m.cur[k] = newMap.Fields
	return v.MarshalLogObject(newMap)
}

// AddBinary implements ObjectEncoder.
func (m *MapObjectEncoder) AddBinary(k string, v []byte) { m.cur[k] = v }

// AddByteString implements ObjectEncoder.
func (m *MapObjectEncoder) AddByteString(k string, v []byte) { m.cur[k] = string(v) }

// AddBool implements ObjectEncoder.
func (m *MapObjectEncoder) AddBool(k string, v bool) { m.cur[k] = v }

// AddDuration implements ObjectEncoder.
func (m MapObjectEncoder) AddDuration(k string, v time.Duration) { m.cur[k] = v }

// AddComplex128 implements ObjectEncoder.

Review comment (suggestion):
I would make this the default value of `arr.elems` since it'll be appended to anyway.

```
arr := &sliceArrayEncoder{elems: make([]interface{})}
```

Code after:

// MapObjectEncoder is an ObjectEncoder backed by a simple
// map[string]interface{}. It's not fast enough for production use, but it's
// helpful in tests.
type MapObjectEncoder struct {
	// Fields contains the entire encoded log context.
	Fields map[string]interface{}
	// cur is a pointer to the namespace we're currently writing to.
	cur map[string]interface{}
}

// NewMapObjectEncoder creates a new map-backed ObjectEncoder.
func NewMapObjectEncoder() *MapObjectEncoder {
	m := make(map[string]interface{})
	return &MapObjectEncoder{
		Fields: m,
		cur:    m,
	}
}

// AddArray implements ObjectEncoder.
func (m *MapObjectEncoder) AddArray(key string, v ArrayMarshaler) error {
	arr := &sliceArrayEncoder{elems: make([]interface{}, 0)}
	err := v.MarshalLogArray(arr)
	m.cur[key] = arr.elems
	return err
}

// AddObject implements ObjectEncoder.
func (m *MapObjectEncoder) AddObject(k string, v ObjectMarshaler) error {
	newMap := NewMapObjectEncoder()
	m.cur[k] = newMap.Fields
	return v.MarshalLogObject(newMap)
}

// AddBinary implements ObjectEncoder.
func (m *MapObjectEncoder) AddBinary(k string, v []byte) { m.cur[k] = v }

// AddByteString implements ObjectEncoder.
func (m *MapObjectEncoder) AddByteString(k string, v []byte) { m.cur[k] = string(v) }

// AddBool implements ObjectEncoder.
func (m *MapObjectEncoder) AddBool(k string, v bool) { m.cur[k] = v }

// AddDuration implements ObjectEncoder.
func (m MapObjectEncoder) AddDuration(k string, v time.Duration) { m.cur[k] = v }

// AddComplex128 implements ObjectEncoder.
func (m *MapObjectEncoder) AddComplex128(k string, v complex128) { m.cur[k] = v }

// AddComplex64 implements ObjectEncoder.