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

Code before:
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import (
	"io"
	"time"
)

// nullEncoder is an Encoder implementation that throws everything away.
type nullEncoder struct{}

// NewNullEncoder creates a fast, no-allocation encoder.
func NewNullEncoder() Encoder {
	return nullEncoder{}
}

func (nullEncoder) Free() {
}

// AddString throws away a string key and value.
func (nullEncoder) AddString(_, _ string) {
}

// AddBool throws away a string key and a boolean value.
func (nullEncoder) AddBool(_ string, _ bool) {
}

// AddInt throws away a string key and integer value.
func (nullEncoder) AddInt(_ string, _ int) {
}

// AddInt64 throws away a string key and int64 value.
func (nullEncoder) AddInt64(_ string, _ int64) {
}

// AddUint throws away a string key and integer value.
func (nullEncoder) AddUint(_ string, _ uint) {
}

// AddUint64 throws away a string key and integer value.
func (nullEncoder) AddUint64(_ string, _ uint64) {
}

// AddFloat64 throws away a string key and float64 value.
func (nullEncoder) AddFloat64(_ string, _ float64) {
}

// AddMarshaler applies a LogMarshaler to nothingness.
func (enc nullEncoder) AddMarshaler(_ string, obj LogMarshaler) error {
	// is it part of the contract that we call this?
	return obj.MarshalLog(enc)
}

// AddObject does nothing with an arbitrary object.
func (nullEncoder) AddObject(_ string, _ interface{}) error {
	return nil
}

// Clone copies the current encoder, including any data already encoded.
func (enc nullEncoder) Clone() Encoder {
	return enc
}

// WriteEntry writes nothing to the supplied writer, but demands a valid writer.
// It's safe to call from multiple goroutines.
func (nullEncoder) WriteEntry(sink io.Writer, _ string, _ Level, _ time.Time) error {
	if sink == nil {
		return errNilSink
	}
	return nil
}


Review comment (suggestion):
Good question, I don't think so. The user's interaction will typically be through `zap.Marshaler([...])` which is lazy, it calls the marshal method if the log message needs to be encoded. However if the log level is disabled or has been sampled away, then the Marshal method is not called.

I think it should be similar for `AddMarshaler` -- the implementation can choose not to call it.


Code after:
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package zap

import (
	"io"
	"time"
)

// nullEncoder is an Encoder implementation that throws everything away.
type nullEncoder struct{}

var _nullEncoder nullEncoder

// NullEncoder returns the fast, no-allocation encoder.
func NullEncoder() Encoder {
	return _nullEncoder
}

func (nullEncoder) Free() {}

func (nullEncoder) AddString(_, _ string)          {}
func (nullEncoder) AddBool(_ string, _ bool)       {}
func (nullEncoder) AddInt(_ string, _ int)         {}
func (nullEncoder) AddInt64(_ string, _ int64)     {}
func (nullEncoder) AddUint(_ string, _ uint)       {}
func (nullEncoder) AddUint64(_ string, _ uint64)   {}
func (nullEncoder) AddFloat64(_ string, _ float64) {}

func (nullEncoder) AddMarshaler(_ string, _ LogMarshaler) error { return nil }
func (nullEncoder) AddObject(_ string, _ interface{}) error     { return nil }

// Clone copies the current encoder, including any data already encoded.
func (nullEncoder) Clone() Encoder {
	return _nullEncoder
}

// WriteEntry writes nothing to the supplied writer, but demands a valid writer.
// It's safe to call from multiple goroutines.
func (nullEncoder) WriteEntry(sink io.Writer, _ string, _ Level, _ time.Time) error {
	if sink == nil {
		return errNilSink
	}
	return nil
}