From 0a2ea88a9867bcb282e6faabf8e91a8e69a0c5e1 Mon Sep 17 00:00:00 2001 From: Marcin Podlodowski Date: Wed, 22 Aug 2018 02:05:45 +0200 Subject: [PATCH 1/2] Add simplemap backend --- backend/simplemap/simplemap.go | 56 +++++++++++++++++++++++++++++ backend/simplemap/simplemap_test.go | 54 ++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 backend/simplemap/simplemap.go create mode 100644 backend/simplemap/simplemap_test.go diff --git a/backend/simplemap/simplemap.go b/backend/simplemap/simplemap.go new file mode 100644 index 0000000..684e17d --- /dev/null +++ b/backend/simplemap/simplemap.go @@ -0,0 +1,56 @@ +package simplemap + +import ( + "time" + "fmt" + "strconv" + "github.com/heetch/confita/backend" + "context" +) + +// Backend that loads config from map +type Backend struct{ + theMap map[string]interface{} +} + +// NewBackend creates a simplemap backend. +func NewBackend(theMap map[string]interface{}) *Backend { + return &Backend{ + theMap: theMap, + } +} + +// Get loads the given key from the map +func (b *Backend) Get(ctx context.Context, key string) ([]byte, error) { + val := b.theMap[key] + if val == nil { + return nil, backend.ErrNotFound + } + + if str, ok := val.(string); ok { + return []byte(str), nil + } + + if u, ok := val.(uint); ok { + return []byte(strconv.FormatUint(uint64(u), 10)), nil + } + + if i, ok := val.(int); ok { + return []byte(strconv.FormatInt(int64(i), 10)), nil + } + + if f, ok := val.(float64); ok { + return []byte(fmt.Sprintf("%g", f)), nil + } + + if d, ok := val.(time.Duration); ok { + return []byte(fmt.Sprintf("%s", d)), nil + } + + return nil, backend.ErrNotFound +} + +// Name returns the name of the flags backend. +func (b *Backend) Name() string { + return "simplemap" +} \ No newline at end of file diff --git a/backend/simplemap/simplemap_test.go b/backend/simplemap/simplemap_test.go new file mode 100644 index 0000000..00f3fb7 --- /dev/null +++ b/backend/simplemap/simplemap_test.go @@ -0,0 +1,54 @@ +package simplemap_test + +import ( + "github.com/heetch/confita/backend" + "github.com/stretchr/testify/assert" + "context" + "github.com/heetch/confita/backend/simplemap" + "time" + "testing" + "github.com/stretchr/testify/require" +) + +func TestSimplemapBackend(t *testing.T) { + type config struct { + Name string + Age int + Balance float64 + Timeout time.Duration + } + + b := simplemap.NewBackend(map[string]interface{}{ + "Name": "Bob", + "Age": uint(30), + "Negative": -10, + "Balance": 1234.56, + "Timeout": 10 * time.Second, + }) + + assert.Equal(t, "simplemap", b.Name()) + + val, err := b.Get(context.Background(), "Name") + require.NoError(t, err) + assert.Equal(t, "Bob", string(val)) + + val, err = b.Get(context.Background(), "Age") + require.NoError(t, err) + assert.Equal(t, "30", string(val)) + + val, err = b.Get(context.Background(), "Negative") + require.NoError(t, err) + assert.Equal(t, "-10", string(val)) + + val, err = b.Get(context.Background(), "Balance") + require.NoError(t, err) + assert.Equal(t, "1234.56", string(val)) + + val, err = b.Get(context.Background(), "Timeout") + require.NoError(t, err) + assert.Equal(t, "10s", string(val)) + + _, err = b.Get(context.Background(), "NotExists") + require.Error(t, err) + assert.Equal(t, backend.ErrNotFound, err) +} \ No newline at end of file From e5c9c40c865321434a32cbc6ab4079b8c758f7a6 Mon Sep 17 00:00:00 2001 From: Marcin Podlodowski Date: Wed, 26 Sep 2018 02:13:08 +0200 Subject: [PATCH 2/2] simplemap StructLoader approach --- backend/simplemap/simplemap.go | 54 +++++++++++---------------- backend/simplemap/simplemap_test.go | 57 +++++++++++------------------ 2 files changed, 42 insertions(+), 69 deletions(-) diff --git a/backend/simplemap/simplemap.go b/backend/simplemap/simplemap.go index 684e17d..fec77d1 100644 --- a/backend/simplemap/simplemap.go +++ b/backend/simplemap/simplemap.go @@ -1,16 +1,16 @@ package simplemap import ( - "time" - "fmt" - "strconv" - "github.com/heetch/confita/backend" + "github.com/heetch/confita" + "github.com/pkg/errors" + "reflect" + "context" ) // Backend that loads config from map -type Backend struct{ - theMap map[string]interface{} +type Backend struct { + theMap map[string]interface{} } // NewBackend creates a simplemap backend. @@ -20,37 +20,25 @@ func NewBackend(theMap map[string]interface{}) *Backend { } } -// Get loads the given key from the map -func (b *Backend) Get(ctx context.Context, key string) ([]byte, error) { - val := b.theMap[key] - if val == nil { - return nil, backend.ErrNotFound - } - - if str, ok := val.(string); ok { - return []byte(str), nil - } - - if u, ok := val.(uint); ok { - return []byte(strconv.FormatUint(uint64(u), 10)), nil - } - - if i, ok := val.(int); ok { - return []byte(strconv.FormatInt(int64(i), 10)), nil - } - - if f, ok := val.(float64); ok { - return []byte(fmt.Sprintf("%g", f)), nil - } - - if d, ok := val.(time.Duration); ok { - return []byte(fmt.Sprintf("%s", d)), nil +// LoadStruct takes a struct config and loads the map into it +func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) error { + for _, f := range cfg.Fields { + mapVal := b.theMap[f.Key] + if mapVal == nil { + continue + } + mapRef := reflect.ValueOf(mapVal) + f.Value.Set(mapRef) } + return nil +} - return nil, backend.ErrNotFound +// Get is not implemented. +func (b *Backend) Get(ctx context.Context, key string) ([]byte, error) { + return nil, errors.New("not implemented") } // Name returns the name of the flags backend. func (b *Backend) Name() string { return "simplemap" -} \ No newline at end of file +} diff --git a/backend/simplemap/simplemap_test.go b/backend/simplemap/simplemap_test.go index 00f3fb7..6a444f4 100644 --- a/backend/simplemap/simplemap_test.go +++ b/backend/simplemap/simplemap_test.go @@ -1,54 +1,39 @@ package simplemap_test import ( - "github.com/heetch/confita/backend" - "github.com/stretchr/testify/assert" "context" + "github.com/heetch/confita" "github.com/heetch/confita/backend/simplemap" - "time" - "testing" "github.com/stretchr/testify/require" + "testing" + "time" ) func TestSimplemapBackend(t *testing.T) { type config struct { - Name string - Age int - Balance float64 - Timeout time.Duration + Name string `config:"Name"` + Age int `config:"Age"` + Negative int `config:"Negative"` + Balance float64 `config:"Balance"` + Timeout time.Duration `config:"Timeout"` } b := simplemap.NewBackend(map[string]interface{}{ - "Name": "Bob", - "Age": uint(30), + "Name": "Bob", + "Age": 30, "Negative": -10, - "Balance": 1234.56, - "Timeout": 10 * time.Second, + "Balance": 1234.56, + "Timeout": 10 * time.Second, }) - - assert.Equal(t, "simplemap", b.Name()) - - val, err := b.Get(context.Background(), "Name") - require.NoError(t, err) - assert.Equal(t, "Bob", string(val)) - val, err = b.Get(context.Background(), "Age") - require.NoError(t, err) - assert.Equal(t, "30", string(val)) - - val, err = b.Get(context.Background(), "Negative") - require.NoError(t, err) - assert.Equal(t, "-10", string(val)) + var c config + require.Equal(t, "simplemap", b.Name()) + err := confita.NewLoader(b).Load(context.Background(), &c) - val, err = b.Get(context.Background(), "Balance") require.NoError(t, err) - assert.Equal(t, "1234.56", string(val)) - - val, err = b.Get(context.Background(), "Timeout") - require.NoError(t, err) - assert.Equal(t, "10s", string(val)) - - _, err = b.Get(context.Background(), "NotExists") - require.Error(t, err) - assert.Equal(t, backend.ErrNotFound, err) -} \ No newline at end of file + require.Equal(t, "Bob", c.Name) + require.Equal(t, 30, c.Age) + require.Equal(t, -10, c.Negative) + require.Equal(t, 1234.56, c.Balance) + require.Equal(t, 10*time.Second, c.Timeout) +}