diff --git a/fs/config/configmap/configmap.go b/fs/config/configmap/configmap.go new file mode 100644 index 000000000..2d1267a22 --- /dev/null +++ b/fs/config/configmap/configmap.go @@ -0,0 +1,86 @@ +// Package configmap provides an abstraction for reading and writing config +package configmap + +// Getter provides an interface to get config items +type Getter interface { + // Get should get an item with the key passed in and return + // the value. If the item is found then it should return true, + // otherwise false. + Get(key string) (value string, ok bool) +} + +// Setter provides an interface to set config items +type Setter interface { + // Set should set an item into persistent config store. + Set(key, value string) +} + +// Mapper provides an interface to read and write config +type Mapper interface { + Getter + Setter +} + +// Map provides a wrapper around multiple Setter and +// Getter interfaces. +type Map struct { + setters []Setter + getters []Getter +} + +// New returns an empty Map +func New() *Map { + return &Map{} +} + +// AddGetter appends a getter onto the end of the getters +func (c *Map) AddGetter(getter Getter) *Map { + c.getters = append(c.getters, getter) + return c +} + +// AddGetters appends multiple getters onto the end of the getters +func (c *Map) AddGetters(getters ...Getter) *Map { + c.getters = append(c.getters, getters...) + return c +} + +// AddSetter appends a setter onto the end of the setters +func (c *Map) AddSetter(setter Setter) *Map { + c.setters = append(c.setters, setter) + return c +} + +// Get gets an item with the key passed in and return the value from +// the first getter. If the item is found then it returns true, +// otherwise false. +func (c *Map) Get(key string) (value string, ok bool) { + for _, do := range c.getters { + value, ok = do.Get(key) + if ok { + return value, ok + } + } + return "", false +} + +// Set sets an item into all the stored setters. +func (c *Map) Set(key, value string) { + for _, do := range c.setters { + do.Set(key, value) + } +} + +// Simple is a simple Mapper for testing +type Simple map[string]string + +// Get the value +func (c Simple) Get(key string) (value string, ok bool) { + value, ok = c[key] + return value, ok +} + +// Set the value +func (c Simple) Set(key, value string) { + c[key] = value +} diff --git a/fs/config/configmap/configmap_test.go b/fs/config/configmap/configmap_test.go new file mode 100644 index 000000000..51f3dcc95 --- /dev/null +++ b/fs/config/configmap/configmap_test.go @@ -0,0 +1,91 @@ +package configmap + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + _ Mapper = (Simple)(nil) + _ Getter = (Simple)(nil) + _ Setter = (Simple)(nil) +) + +func TestConfigMapGet(t *testing.T) { + m := New() + + value, found := m.Get("config1") + assert.Equal(t, "", value) + assert.Equal(t, false, found) + + value, found = m.Get("config2") + assert.Equal(t, "", value) + assert.Equal(t, false, found) + + m1 := Simple{ + "config1": "one", + } + + m.AddGetter(m1) + + value, found = m.Get("config1") + assert.Equal(t, "one", value) + assert.Equal(t, true, found) + + value, found = m.Get("config2") + assert.Equal(t, "", value) + assert.Equal(t, false, found) + + m2 := Simple{ + "config1": "one2", + "config2": "two2", + } + + m.AddGetter(m2) + + value, found = m.Get("config1") + assert.Equal(t, "one", value) + assert.Equal(t, true, found) + + value, found = m.Get("config2") + assert.Equal(t, "two2", value) + assert.Equal(t, true, found) + +} + +func TestConfigMapSet(t *testing.T) { + m := New() + + m1 := Simple{ + "config1": "one", + } + m2 := Simple{ + "config1": "one2", + "config2": "two2", + } + + m.AddSetter(m1).AddSetter(m2) + + m.Set("config2", "potato") + + assert.Equal(t, Simple{ + "config1": "one", + "config2": "potato", + }, m1) + assert.Equal(t, Simple{ + "config1": "one2", + "config2": "potato", + }, m2) + + m.Set("config1", "beetroot") + + assert.Equal(t, Simple{ + "config1": "beetroot", + "config2": "potato", + }, m1) + assert.Equal(t, Simple{ + "config1": "beetroot", + "config2": "potato", + }, m2) +}