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

Code before:
	}
	enc.bytes = append(enc.bytes, "false"...)
}

// AddInt adds a string key and integer value to the encoder's fields. The key
// is JSON-escaped.
func (enc *jsonEncoder) AddInt(key string, val int) {
	enc.AddInt64(key, int64(val))
}

// AddInt64 adds a string key and int64 value to the encoder's fields. The key
// is JSON-escaped.
func (enc *jsonEncoder) AddInt64(key string, val int64) {
	enc.addKey(key)
	enc.bytes = strconv.AppendInt(enc.bytes, val, 10)
}

// AddFloat64 adds a string key and float64 value to the encoder's fields. The
// key is JSON-escaped, and the floating-point value is encoded using
// strconv.FormatFloat's 'g' option (exponential notation for large exponents,
// grade-school notation otherwise).
func (enc *jsonEncoder) AddFloat64(key string, val float64) {
	enc.addKey(key)
	if math.IsNaN(val) {
		enc.bytes = append(enc.bytes, `"NaN"`...)
		return
	}
	if math.IsInf(val, 1) {
		enc.bytes = append(enc.bytes, `"+Inf"`...)
		return
	}
	if math.IsInf(val, -1) {
		enc.bytes = append(enc.bytes, `"-Inf"`...)
		return
	}
	enc.bytes = strconv.AppendFloat(enc.bytes, val, 'g', -1, 64)
}

// Nest allows the caller to populate a nested object under the provided key.
func (enc *jsonEncoder) Nest(key string, f func(KeyValue) error) error {
	enc.addKey(key)
	enc.bytes = append(enc.bytes, '{')
	err := f(enc)
	enc.bytes = append(enc.bytes, '}')
	return err
}

// AddMarshaler adds a LogMarshaler to the encoder's fields.
//
// TODO: Encode the error into the message instead of returning.
func (enc *jsonEncoder) AddMarshaler(key string, obj LogMarshaler) error {

Review comment (suggestion):
Hmm should we be encoding the same key with a different type? What do you think of the idea of using something like "key-error" or something?

It's a pain JSON doesn't allow `NaN` or infinity


Code after:
	}
	enc.bytes = append(enc.bytes, "false"...)
}

// AddInt adds a string key and integer value to the encoder's fields. The key
// is JSON-escaped.
func (enc *jsonEncoder) AddInt(key string, val int) {
	enc.AddInt64(key, int64(val))
}

// AddInt64 adds a string key and int64 value to the encoder's fields. The key
// is JSON-escaped.
func (enc *jsonEncoder) AddInt64(key string, val int64) {
	enc.addKey(key)
	enc.bytes = strconv.AppendInt(enc.bytes, val, 10)
}

// AddFloat64 adds a string key and float64 value to the encoder's fields. The
// key is JSON-escaped, and the floating-point value is encoded using
// strconv.FormatFloat's 'g' option (exponential notation for large exponents,
// grade-school notation otherwise).
func (enc *jsonEncoder) AddFloat64(key string, val float64) {
	enc.addKey(key)
	switch {
	case math.IsNaN(val):
		enc.bytes = append(enc.bytes, `"NaN"`...)
	case math.IsInf(val, 1):
		enc.bytes = append(enc.bytes, `"+Inf"`...)
	case math.IsInf(val, -1):
		enc.bytes = append(enc.bytes, `"-Inf"`...)
	default:
		enc.bytes = strconv.AppendFloat(enc.bytes, val, 'g', -1, 64)
	}
}

// Nest allows the caller to populate a nested object under the provided key.
func (enc *jsonEncoder) Nest(key string, f func(KeyValue) error) error {
	enc.addKey(key)
	enc.bytes = append(enc.bytes, '{')
	err := f(enc)
	enc.bytes = append(enc.bytes, '}')
	return err
}

// AddMarshaler adds a LogMarshaler to the encoder's fields.
//
// TODO: Encode the error into the message instead of returning.
func (enc *jsonEncoder) AddMarshaler(key string, obj LogMarshaler) error {
	return enc.Nest(key, func(kv KeyValue) error {
		return obj.MarshalLog(kv)
	})