Skip to content

Commit

Permalink
Add support for slog.Level fields
Browse files Browse the repository at this point in the history
  • Loading branch information
itzg committed Nov 11, 2024
1 parent 07e1256 commit eb08ffd
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
19 changes: 19 additions & 0 deletions additional.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package flagsfiller

import (
"log/slog"

Check failure on line 4 in additional.go

View workflow job for this annotation

GitHub Actions / build

package log/slog is not in GOROOT (/opt/hostedtoolcache/go/1.19.13/x64/src/log/slog)
"reflect"
)

func init() {
RegisterSimpleType(slogLevelConverter)
}

func slogLevelConverter(s string, _ reflect.StructTag) (slog.Level, error) {
var level slog.Level
err := level.UnmarshalText([]byte(s))
if err != nil {
return slog.LevelInfo, err
}
return level, nil
}
57 changes: 57 additions & 0 deletions addtional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package flagsfiller_test

import (
"flag"
"log/slog"
"net"
"net/netip"
"testing"
Expand Down Expand Up @@ -117,3 +118,59 @@ func TestTextUnmarshalerType(t *testing.T) {

assert.Equal(t, netip.AddrFrom4([4]byte{1, 2, 3, 4}), config.Addr)
}

func TestSlogLevels(t *testing.T) {
tests := []struct {
name string
value string
expected slog.Level
}{
{
name: "info",
value: "info",
expected: slog.LevelInfo,
},
{
name: "error",
value: "error",
expected: slog.LevelError,
},
{
name: "numeric offset",
// Borrowed from https://pkg.go.dev/log/slog#Level.UnmarshalText
value: "Error-8",
expected: slog.LevelInfo,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var args struct {
Level slog.Level
}

var flagset flag.FlagSet
err := flagsfiller.New().Fill(&flagset, &args)
require.NoError(t, err)

err = flagset.Parse([]string{"--level", test.value})
require.NoError(t, err)

assert.Equal(t, test.expected, args.Level)
})
}
}

func TestSlogLevelWithDefault(t *testing.T) {
var args struct {
Level slog.Level `default:"info"`
}

var flagset flag.FlagSet
err := flagsfiller.New().Fill(&flagset, &args)
require.NoError(t, err)

err = flagset.Parse([]string{})
require.NoError(t, err)

assert.Equal(t, slog.LevelInfo, args.Level)
}
1 change: 1 addition & 0 deletions docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ FlagSetFiller also supports following field types:
- net.IPNet: format used by net.ParseCIDR()
- net.HardwareAddr (MAC addr): format used by net.ParseMAC()
- time.Time: format is the layout string used by time.Parse(), default layout is time.DateTime, could be overriden by field tag "layout"
- slog.Level: parsed as specified by https://pkg.go.dev/log/slog#Level.UnmarshalText, such as "info"
# Environment variable mapping
Expand Down
2 changes: 1 addition & 1 deletion flagset.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func (f *FlagSetFiller) processField(flagSet *flag.FlagSet, fieldRef interface{}
if isSupportedStruct(fieldRef) {
handler := extendedTypes[getTypeName(t)]
err = handler(tag, fieldRef, hasDefaultTag, tagDefault, flagSet, renamed, usage, aliases)

return err
}

switch {
Expand Down
2 changes: 1 addition & 1 deletion general.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"strings"
)

// this is a list of addtional supported types(include struct), like time.Time, that walkFields() won't walk into,
// this is a list of additional supported types(include struct), like time.Time, that walkFields() won't walk into,
// the key is the is string returned by the getTypeName(<type>),
// each supported type need to be added in this map in init()
var extendedTypes = make(map[string]handlerFunc)
Expand Down

0 comments on commit eb08ffd

Please sign in to comment.