Skip to content

Commit

Permalink
Add a map source interface
Browse files Browse the repository at this point in the history
  • Loading branch information
dearchap committed Nov 21, 2024
1 parent acc590b commit 596e7c5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
16 changes: 12 additions & 4 deletions godoc-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -854,11 +854,19 @@ func (i MapBase[T, C, VC]) ToString(t map[string]T) string
func (i *MapBase[T, C, VC]) Value() map[string]T
Value returns the mapping of values set by this flag

type MapSource struct {
// Has unexported fields.
type MapSource interface {
fmt.Stringer
fmt.GoStringer

// Lookup returns the value from the source based on key
// and if it was found
// or returns an empty string and false
Lookup(string) (any, bool)
}
MapSource is a source which can be used to look up a value based on a key
typically for use with a cli.Flag

func NewMapSource(name string, m map[any]any) *MapSource
func NewMapSource(name string, m map[any]any) MapSource

type MultiError interface {
error
Expand Down Expand Up @@ -1012,7 +1020,7 @@ func EnvVar(key string) ValueSource

func File(path string) ValueSource

func NewMapValueSource(key string, ms *MapSource) ValueSource
func NewMapValueSource(key string, ms MapSource) ValueSource

type ValueSourceChain struct {
Chain []ValueSource
Expand Down
36 changes: 27 additions & 9 deletions value_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ type EnvValueSource interface {
Key() string
}

// MapSource is a source which can be used to look up a value
// based on a key
// typically for use with a cli.Flag
type MapSource interface {
fmt.Stringer
fmt.GoStringer

// Lookup returns the value from the source based on key
// and if it was found
// or returns an empty string and false
Lookup(string) (any, bool)
}

// ValueSourceChain contains an ordered series of ValueSource that
// allows for lookup where the first ValueSource to resolve is
// returned
Expand Down Expand Up @@ -159,19 +172,24 @@ func Files(paths ...string) ValueSourceChain {
return vsc
}

type MapSource struct {
type mapSource struct {
name string
m map[any]any
}

func NewMapSource(name string, m map[any]any) *MapSource {
return &MapSource{
func NewMapSource(name string, m map[any]any) MapSource {
return &mapSource{
name: name,
m: m,
}
}

func (ms *MapSource) lookup(name string) (any, bool) {
func (ms *mapSource) String() string { return fmt.Sprintf("map source %[1]q", ms.name) }
func (ms *mapSource) GoString() string {
return fmt.Sprintf("&mapSource{name:%[1]q}", ms.name)
}

func (ms *mapSource) Lookup(name string) (any, bool) {
// nestedVal checks if the name has '.' delimiters.
// If so, it tries to traverse the tree by the '.' delimited sections to find
// a nested value for the key.
Expand Down Expand Up @@ -205,26 +223,26 @@ func (ms *MapSource) lookup(name string) (any, bool) {

type mapValueSource struct {
key string
ms *MapSource
ms MapSource
}

func NewMapValueSource(key string, ms *MapSource) ValueSource {
func NewMapValueSource(key string, ms MapSource) ValueSource {
return &mapValueSource{
key: key,
ms: ms,
}
}

func (mvs *mapValueSource) String() string {
return fmt.Sprintf("map source key %[1]q from %[2]q", mvs.key, mvs.ms.name)
return fmt.Sprintf("key %[1]q from %[2]s", mvs.key, mvs.ms.String())
}

func (mvs *mapValueSource) GoString() string {
return fmt.Sprintf("&mapValueSource{key:%[1]q, src:%[2]q}", mvs.key, mvs.ms.m)
return fmt.Sprintf("&mapValueSource{key:%[1]q, src:%[2]s}", mvs.key, mvs.ms.GoString())
}

func (mvs *mapValueSource) Lookup() (string, bool) {
if v, ok := mvs.ms.lookup(mvs.key); !ok {
if v, ok := mvs.ms.Lookup(mvs.key); !ok {
return "", false
} else {
return fmt.Sprintf("%+v", v), true
Expand Down
4 changes: 2 additions & 2 deletions value_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,6 @@ func TestMapValueSourceStringer(t *testing.T) {
}
mvs := NewMapValueSource("bar", NewMapSource("test", m))

assert.Equal(t, `&mapValueSource{key:"bar", src:map["foo":map["bar":'\n']]}`, mvs.GoString())
assert.Equal(t, `map source key "bar" from "test"`, mvs.String())
assert.Equal(t, `&mapValueSource{key:"bar", src:&mapSource{name:"test"}}`, mvs.GoString())
assert.Equal(t, `key "bar" from map source "test"`, mvs.String())
}

0 comments on commit 596e7c5

Please sign in to comment.