2026-03-19 16:37:57 +08:00

137 lines
2.3 KiB
Go

package stdlibx
import (
"errors"
"strings"
)
type LevelMapper func(text string, fallbackLevel int) int
type Options struct {
Prefix string
Flags int
ShowStd bool
TrimNewline bool
LevelMapper LevelMapper
}
type Option func(*Options)
func DefaultOptions() Options {
return Options{
Prefix: "",
Flags: 0,
ShowStd: false,
TrimNewline: true,
LevelMapper: nil,
}
}
func WithPrefix(prefix string) Option {
return func(options *Options) {
if options == nil {
return
}
options.Prefix = prefix
}
}
func WithFlags(flags int) Option {
return func(options *Options) {
if options == nil {
return
}
options.Flags = flags
}
}
func WithShowStd(show bool) Option {
return func(options *Options) {
if options == nil {
return
}
options.ShowStd = show
}
}
func WithTrimNewline(trim bool) Option {
return func(options *Options) {
if options == nil {
return
}
options.TrimNewline = trim
}
}
func WithLevelMapper(mapper LevelMapper) Option {
return func(options *Options) {
if options == nil {
return
}
options.LevelMapper = mapper
}
}
func NormalizeOptions(opts []Option) Options {
options := DefaultOptions()
for _, option := range opts {
if option == nil {
continue
}
option(&options)
}
return options
}
type EmitFunc func(level int, showStd bool, text string)
type Writer struct {
level int
showStd bool
trimNewline bool
levelMapper LevelMapper
emit EmitFunc
}
func NewWriter(level int, options Options, emit EmitFunc) *Writer {
return &Writer{
level: level,
showStd: options.ShowStd,
trimNewline: options.TrimNewline,
levelMapper: options.LevelMapper,
emit: emit,
}
}
func (writer *Writer) SetShowStd(show bool) {
if writer == nil {
return
}
writer.showStd = show
}
func (writer *Writer) SetTrimNewline(trim bool) {
if writer == nil {
return
}
writer.trimNewline = trim
}
func (writer *Writer) Write(data []byte) (int, error) {
if writer == nil || writer.emit == nil {
return 0, errors.New("level writer logger is nil")
}
text := string(data)
if writer.trimNewline {
text = strings.TrimRight(text, "\r\n")
}
if text != "" {
level := writer.level
if writer.levelMapper != nil {
level = writer.levelMapper(text, level)
}
writer.emit(level, writer.showStd, text)
}
return len(data), nil
}