Skip to content

Commit

Permalink
WIP: Sketch of an implementation for uber-go#753
Browse files Browse the repository at this point in the history
  • Loading branch information
jbizzle committed Nov 6, 2019
1 parent a6015e1 commit 269da15
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
30 changes: 30 additions & 0 deletions field.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,25 @@ func Skip() Field {
return Field{Type: zapcore.SkipType}
}

// nilField returns a field which will marshal explicitly as null. See original
// motivation in https://github.com/uber-go/zap/issues/753 .
//
// TODO: We might also consider a way to widen the overall APIs in this package,
// ultimately exporting this function, by:
//
// - Adding zapcore.NilType
//
// - Adding zapcore.ObjectEncoder.AddNil()
//
// Doing so will provide encoder implementations a more efficient way to encode
// nil (primary benefit), and would also help with debugging or maintaining the
// implementation of zap itself (secondary benefit).
//
// But we avoid doing this until we are ready for a major version change, since
// it would potentially break users of this package who switch on
// zapcore.FieldType or which have implemented zapcore.ObjectEncoder.
func nilField(key string) Field { return Reflect(key, nil) }

// Binary constructs a field that carries an opaque binary blob.
//
// Binary data is serialized in an encoding-appropriate format. For example,
Expand All @@ -56,6 +75,15 @@ func Bool(key string, val bool) Field {
return Field{Key: key, Type: zapcore.BoolType, Integer: ival}
}

// Boolp constructs a field that carries a *bool. The returned Field will safely
// and explicitly represent `nil` when appropriate.
func Boolp(key string, val *bool) Field {
if val == nil {
return nilField(key)
}
return Bool(key, *val)
}

// ByteString constructs a field that carries UTF-8 encoded text as a []byte.
// To log opaque binary blobs (which aren't necessarily valid UTF-8), use
// Binary.
Expand Down Expand Up @@ -224,6 +252,8 @@ func Any(key string, value interface{}) Field {
return Array(key, val)
case bool:
return Bool(key, val)
case *bool:
return Boolp(key, val)
case []bool:
return Bools(key, val)
case complex128:
Expand Down
12 changes: 12 additions & 0 deletions field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ func TestFieldConstructors(t *testing.T) {
name := username("phil")
ints := []int{5, 6}

// Helpful values for use in constructing pointers to primitives below.
var (
boolTrue = true
// TODO(goldfish): round out the rest of the primitive types for
// https://github.com/uber-go/zap/issues/753
)

tests := []struct {
name string
field Field
Expand Down Expand Up @@ -91,6 +98,7 @@ func TestFieldConstructors(t *testing.T) {
{"Uint8", Field{Key: "k", Type: zapcore.Uint8Type, Integer: 1}, Uint8("k", 1)},
{"Uintptr", Field{Key: "k", Type: zapcore.UintptrType, Integer: 10}, Uintptr("k", 0xa)},
{"Reflect", Field{Key: "k", Type: zapcore.ReflectType, Interface: ints}, Reflect("k", ints)},
{"Reflect", Field{Key: "k", Type: zapcore.ReflectType}, Reflect("k", nil)},
{"Stringer", Field{Key: "k", Type: zapcore.StringerType, Interface: addr}, Stringer("k", addr)},
{"Object", Field{Key: "k", Type: zapcore.ObjectMarshalerType, Interface: name}, Object("k", name)},
{"Any:ObjectMarshaler", Any("k", name), Object("k", name)},
Expand Down Expand Up @@ -139,6 +147,10 @@ func TestFieldConstructors(t *testing.T) {
{"Any:Duration", Any("k", time.Second), Duration("k", time.Second)},
{"Any:Durations", Any("k", []time.Duration{time.Second}), Durations("k", []time.Duration{time.Second})},
{"Any:Fallback", Any("k", struct{}{}), Reflect("k", struct{}{})},
{"Ptr:Bool", Boolp("k", nil), Reflect("k", nil)},
{"Ptr:Bool", Boolp("k", &boolTrue), Bool("k", true)},
{"Any:PtrBool", Any("k", (*bool)(nil)), Reflect("k", nil)},
{"Any:PtrBool", Any("k", &boolTrue), Bool("k", true)},
{"Namespace", Namespace("k"), Field{Key: "k", Type: zapcore.NamespaceType}},
}

Expand Down
2 changes: 2 additions & 0 deletions zapcore/json_encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func TestJSONEncodeEntry(t *testing.T) {
"so": "passes",
"answer": 42,
"common_pie": 3.14,
"null_value": null,
"such": {
"aee": "lol",
"bee": 123,
Expand All @@ -84,6 +85,7 @@ func TestJSONEncodeEntry(t *testing.T) {
zap.String("so", "passes"),
zap.Int("answer", 42),
zap.Float64("common_pie", 3.14),
zap.Reflect("null_value", nil),
zap.Reflect("such", foo{
A: "lol",
B: 123,
Expand Down

0 comments on commit 269da15

Please sign in to comment.