<commit_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 (
	"fmt"

	"go.uber.org/zap/zapcore"
)

const oddNumberErrMsg = "Passed an odd number of keys and values to SugaredLogger, ignoring last."

// A SugaredLogger wraps the core Logger functionality in a slower, but less
// verbose, API.
type SugaredLogger struct {
	core Logger
}

// Sugar converts a Logger to a SugaredLogger.
func Sugar(core Logger) *SugaredLogger {
	// TODO: increment caller skip.
	return &SugaredLogger{core}
}

// Desugar unwraps a SugaredLogger, exposing the original Logger.
func Desugar(s *SugaredLogger) Logger {
	// TODO: decrement caller skip.
	return s.core
}

// With adds a variadic number of key-value pairs to the logging context.
// Even-indexed arguments are treated as keys, and are converted to strings
// (with fmt.Sprint) if necessary. The keys are then zipped with the
// odd-indexed values into typed fields using the Any field constructor.
//
// For example,
//   sugaredLogger.With(
//     "hello", "world",
//     "failure", errors.New("oh no"),
//     "count", 42,
//     "user", User{name: "alice"},
//  )
// is the equivalent of
//   coreLogger.With(
//     String("hello", "world"),
//     String("failure", "oh no"),
//     Int("count", 42),
//     Object("user", User{name: "alice"}),
//   )
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger {
	return &SugaredLogger{core: s.core.With(sweetenFields(args, s.core)...)}
}

// WithFields adds structured fields to the logger's context, just like the
// standard Logger's With method.
func (s *SugaredLogger) WithFields(fs ...zapcore.Field) *SugaredLogger {
	return &SugaredLogger{core: s.core.With(fs...)}
}

// Debug logs a message and some key-value pairs at DebugLevel. Keys and values
// are treated as they are in the With method.
func (s *SugaredLogger) Debug(msg interface{}, keysAndValues ...interface{}) {
	if ce := s.core.Check(DebugLevel, sweetenMsg(msg)); ce != nil {
		ce.Write(sweetenFields(keysAndValues, s.core)...)
	}
}

// Debugf uses fmt.Sprintf to construct a dynamic message and logs it at
// DebugLevel. It doesn't add to the message's structured context.
func (s *SugaredLogger) Debugf(template string, args ...interface{}) {
	if ce := s.core.Check(DebugLevel, fmt.Sprintf(template, args...)); ce != nil {
		ce.Write()
	}
}

// Info logs a message and some key-value pairs at InfoLevel. Keys and values
// are treated as they are in the With method.
func (s *SugaredLogger) Info(msg interface{}, keysAndValues ...interface{}) {
	if ce := s.core.Check(InfoLevel, sweetenMsg(msg)); ce != nil {
		ce.Write(sweetenFields(keysAndValues, s.core)...)
	}
}<commit_msg>With should dispatch to WithFields<commit_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 (
	"fmt"

	"go.uber.org/zap/zapcore"
)

const oddNumberErrMsg = "Passed an odd number of keys and values to SugaredLogger, ignoring last."

// A SugaredLogger wraps the core Logger functionality in a slower, but less
// verbose, API.
type SugaredLogger struct {
	core Logger
}

// Sugar converts a Logger to a SugaredLogger.
func Sugar(core Logger) *SugaredLogger {
	// TODO: increment caller skip.
	return &SugaredLogger{core}
}

// Desugar unwraps a SugaredLogger, exposing the original Logger.
func Desugar(s *SugaredLogger) Logger {
	// TODO: decrement caller skip.
	return s.core
}

// With adds a variadic number of key-value pairs to the logging context.
// Even-indexed arguments are treated as keys, and are converted to strings
// (with fmt.Sprint) if necessary. The keys are then zipped with the
// odd-indexed values into typed fields using the Any field constructor.
//
// For example,
//   sugaredLogger.With(
//     "hello", "world",
//     "failure", errors.New("oh no"),
//     "count", 42,
//     "user", User{name: "alice"},
//  )
// is the equivalent of
//   coreLogger.With(
//     String("hello", "world"),
//     String("failure", "oh no"),
//     Int("count", 42),
//     Object("user", User{name: "alice"}),
//   )
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger {
	return s.WithFields(sweetenFields(args, s.core)...)
}

// WithFields adds structured fields to the logger's context, just like the
// standard Logger's With method.
func (s *SugaredLogger) WithFields(fs ...zapcore.Field) *SugaredLogger {
	return &SugaredLogger{core: s.core.With(fs...)}
}

// Debug logs a message and some key-value pairs at DebugLevel. Keys and values
// are treated as they are in the With method.
func (s *SugaredLogger) Debug(msg interface{}, keysAndValues ...interface{}) {
	if ce := s.core.Check(DebugLevel, sweetenMsg(msg)); ce != nil {
		ce.Write(sweetenFields(keysAndValues, s.core)...)
	}
}

// Debugf uses fmt.Sprintf to construct a dynamic message and logs it at
// DebugLevel. It doesn't add to the message's structured context.
func (s *SugaredLogger) Debugf(template string, args ...interface{}) {
	if ce := s.core.Check(DebugLevel, fmt.Sprintf(template, args...)); ce != nil {
		ce.Write()
	}
}

// Info logs a message and some key-value pairs at InfoLevel. Keys and values
// are treated as they are in the With method.
func (s *SugaredLogger) Info(msg interface{}, keysAndValues ...interface{}) {
	if ce := s.core.Check(InfoLevel, sweetenMsg(msg)); ce != nil {
		ce.Write(sweetenFields(keysAndValues, s.core)...)
	}
}
{'fraction_non_alphanumeric': 0.1172, 'fraction_numerical': 0.0021333333333333334, 'mean_word_length': 3.6735202492211836, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5718204', 'n_tokens_mistral': 2238, 'n_tokens_neox': 2139, 'n_words': 919}