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

Code before:
}

// Time constructs a Field with the given key and value. It represents a
// time.Time as nanoseconds since epoch.
func Time(key string, val time.Time) Field {
	return timeField{key, val}
}

// Err constructs a Field that stores err.Error() under the key "error".
func Err(err error) Field {
	return stringField{"error", err.Error()}
}

// Duration constructs a Field with the given key and value. It represents
// durations as an integer number of nanoseconds.
func Duration(key string, val time.Duration) Field {
	return int64Field{key, int64(val)}
}

// Object constructs a field with the given key and zap.Marshaler. It provides a
// flexible, but still type-safe and efficient, way to add user-defined types to
// the logging context.
func Object(key string, val Marshaler) Field {
	return marshalerField{key, val}
}

// Nest takes a key and a variadic number of Fields and creates a nested
// namespace.
func Nest(key string, fields ...Field) Field {
	return nestedField{key, fields}
}

type boolField struct {
	key string
	val bool
}

func (b boolField) addTo(enc encoder) error {
	enc.AddBool(b.key, b.val)
	return nil
}

type float64Field struct {
	key string
	val float64
}

func (f float64Field) addTo(enc encoder) error {
	enc.AddFloat64(f.key, f.val)
	return nil
}

Review comment (suggestion):
Yeah I wasn't sure about this either, let's remove for now. If we really want encoder to control time, then we can serialize to unixnano and deserialize before calling the encoder method.


Code after:
// Float64 constructs a Field with the given key and value. The floating-point
// value is encoded using strconv.FormatFloat's 'g' option (exponential notation
// for large exponents, grade-school notation otherwise).
func Float64(key string, val float64) Field {
	return Field{key: key, fieldType: floatType, ival: int64(math.Float64bits(val))}
}

// Int constructs a Field with the given key and value.
func Int(key string, val int) Field {
	return Field{key: key, fieldType: intType, ival: int64(val)}
}

// Int64 constructs a Field with the given key and value.
func Int64(key string, val int64) Field {
	return Field{key: key, fieldType: int64Type, ival: val}
}

// String constructs a Field with the given key and value.
func String(key string, val string) Field {
	return Field{key: key, fieldType: stringType, str: val}
}

// Time constructs a Field with the given key and value. It represents a
// time.Time as nanoseconds since epoch.
func Time(key string, val time.Time) Field {
	return Int64(key, val.UnixNano())
}

// Err constructs a Field that stores err.Error() under the key "error".
func Err(err error) Field {
	return String("error", err.Error())
}

// Duration constructs a Field with the given key and value. It represents
// durations as an integer number of nanoseconds.
func Duration(key string, val time.Duration) Field {
	return Int64(key, int64(val))
}

// Object constructs a field with the given key and zap.Marshaler. It provides a
// flexible, but still type-safe and efficient, way to add user-defined types to
// the logging context.
func Object(key string, val Marshaler) Field {
	return Field{key: key, fieldType: marshalerType, obj: val}
}

// Nest takes a key and a variadic number of Fields and creates a nested
// namespace.
func Nest(key string, fields ...Field) Field {
	return Field{key: key, fieldType: marshalerType, obj: multiFields(fields)}
}