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 }