Skip to content

Commit

Permalink
add support for getting string slice
Browse files Browse the repository at this point in the history
  • Loading branch information
fzerorubigd committed Jul 26, 2015
1 parent 291e3c2 commit a10ebf5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
4 changes: 3 additions & 1 deletion file_layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"io"
"os"
"reflect"
"testing"

. "github.com/smartystreets/goconvey/convey"
Expand All @@ -18,7 +19,7 @@ func TestFileLayer(t *testing.T) {
path := dir + "/test.json"
path2 := dir + "/invalid.json"

buf := bytes.NewBufferString(`{"str" : "string_data","bool" : true,"integer" : 10 ,"nested" : {"key1" : "string","key2" : 100}}`)
buf := bytes.NewBufferString(`{"slicestr":["a","b","c"],"str" : "string_data","bool" : true,"integer" : 10 ,"nested" : {"key1" : "string","key2" : 100}}`)
bufInvalid := bytes.NewBufferString(`invalid{json}[]`)
f, err := os.Create(path)
So(err, ShouldBeNil)
Expand Down Expand Up @@ -46,6 +47,7 @@ func TestFileLayer(t *testing.T) {
So(o.GetString("nested.key1", ""), ShouldEqual, "string")
So(o.GetInt("nested.key2", 0), ShouldEqual, 100)
So(o.GetBool("bool", false), ShouldBeTrue)
So(reflect.DeepEqual(o.GetStringSlice("slicestr"), []string{"a", "b", "c"}), ShouldBeTrue)

a := New() // Just for test load again
So(a.AddLayer(fl), ShouldBeNil)
Expand Down
45 changes: 42 additions & 3 deletions onion.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ func (o Onion) Get(key string) (interface{}, bool) {
return nil, false
}

// The folowing two function is identical. but converting between map[string] and
// map[interface{}] is not easy, and there is no Generic, so I decide to create
// two almost identical function instead of writing a convertor each time
// The folowing two function are identical. but converting between map[string] and
// map[interface{}] is not easy, and there is no _Generic_ , so I decide to create
// two almost identical function instead of writing a convertor each time.
//
// Some of the loaders like yaml, load inner keys in map[interface{}]interface{}
// some othr like json do it in map[string]interface{} so we should suppport both
func searchStringMap(path []string, m map[string]interface{}) (interface{}, bool) {
Expand Down Expand Up @@ -202,6 +203,44 @@ func (o Onion) GetBool(key string, def bool) bool {
}
}

func (o Onion) getSlice(key string) (interface{}, bool) {
v, ok := o.Get(key)
if !ok {
return nil, false
}

if reflect.TypeOf(v).Kind() != reflect.Slice { // Not good
return nil, false
}

return v, true
}

// GetStringSlice try to get a slice from the config
func (o Onion) GetStringSlice(key string) []string {
var ok bool
v, ok := o.getSlice(key)
if !ok {
return nil
}

switch v.(type) {
case []string:
return v.([]string)
case []interface{}:
vi := v.([]interface{})
res := make([]string, len(vi))
for i := range vi {
if res[i], ok = vi[i].(string); !ok {
return nil
}
}
return res
}

return nil
}

// GetStruct fill an structure base on the config nested set
func (o Onion) GetStruct(prefix string, s interface{}) {
iterateConfig(o, s, prefix)
Expand Down
12 changes: 12 additions & 0 deletions onion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ func TestOnion(t *testing.T) {
t1["other"] = struct{}{}
t1["what"] = getMap("n", "a")
lm.data["yes"] = t1
lm.data["slice1"] = []string{"a", "b", "c"}
lm.data["slice2"] = []interface{}{"a", "b", "c"}
lm.data["slice3"] = []interface{}{"a", "b", true}
lm.data["slice4"] = []int{1, 2, 3}

o := New()
So(o.AddLayer(lm), ShouldBeNil)
Expand Down Expand Up @@ -171,6 +175,14 @@ func TestOnion(t *testing.T) {
So(tmp, ShouldBeNil)
})

Convey("slice test", func() {
So(reflect.DeepEqual(o.GetStringSlice("slice1"), []string{"a", "b", "c"}), ShouldBeTrue)
So(reflect.DeepEqual(o.GetStringSlice("slice2"), []string{"a", "b", "c"}), ShouldBeTrue)
So(o.GetStringSlice("slice3"), ShouldBeNil)
So(o.GetStringSlice("notslice3"), ShouldBeNil)
So(o.GetStringSlice("yes.str1"), ShouldBeNil)
So(o.GetStringSlice("slice4"), ShouldBeNil)
})
})

Convey("Test layer overwrite", t, func() {
Expand Down

0 comments on commit a10ebf5

Please sign in to comment.