forked from goraz/onion
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add default loader and some api break
fixes goraz#2
- Loading branch information
1 parent
4105836
commit 609f7f0
Showing
13 changed files
with
423 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package onion | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
) | ||
|
||
// DefaultLayer is a layer to handle defalt value for layer. | ||
type DefaultLayer interface { | ||
Layer | ||
// SetDefault set a default value for a key | ||
SetDefault(string, interface{}) error | ||
// GetDelimiter is used to get current delimiter for this layer. since | ||
// this layer needs to work with keys, the delimiter is needed | ||
GetDelimiter() string | ||
// SetDelimiter is used to set delimiter on this layer | ||
SetDelimiter(d string) | ||
} | ||
|
||
type defaultLayer struct { | ||
delimiter string | ||
data map[string]interface{} | ||
} | ||
|
||
// Again, the case of two identical function and not convert one to another | ||
func stringSetDefault(k []string, v interface{}, scope map[string]interface{}) error { | ||
if len(k) == 1 { | ||
// this is the key. just set it | ||
scope[k[0]] = v | ||
return nil | ||
} | ||
t, ok := scope[k[0]] | ||
if ok { | ||
// the key is already there. check if its another map? | ||
switch t.(type) { | ||
case map[string]interface{}: | ||
return stringSetDefault(k[1:], v, scope[k[0]].(map[string]interface{})) | ||
case map[interface{}]interface{}: | ||
return interfaceSetDefault(k[1:], v, scope[k[0]].(map[interface{}]interface{})) | ||
default: | ||
return errors.New("the key is not a map") | ||
} | ||
} | ||
|
||
scope[k[0]] = make(map[string]interface{}) | ||
return stringSetDefault(k[1:], v, scope[k[0]].(map[string]interface{})) | ||
} | ||
|
||
func interfaceSetDefault(k []string, v interface{}, scope map[interface{}]interface{}) error { | ||
if len(k) == 1 { | ||
// this is the key. just set it | ||
scope[k[0]] = v | ||
return nil | ||
} | ||
t, ok := scope[k[0]] | ||
if ok { | ||
// the key is already there. check if its another map? | ||
switch t.(type) { | ||
case map[string]interface{}: | ||
return stringSetDefault(k[1:], v, scope[k[0]].(map[string]interface{})) | ||
case map[interface{}]interface{}: | ||
return interfaceSetDefault(k[1:], v, scope[k[0]].(map[interface{}]interface{})) | ||
default: | ||
return errors.New("the key is not a map") | ||
} | ||
} | ||
|
||
scope[k[0]] = make(map[string]interface{}) | ||
return stringSetDefault(k[1:], v, scope[k[0]].(map[string]interface{})) | ||
} | ||
|
||
func (dl *defaultLayer) Load() (map[string]interface{}, error) { | ||
return dl.data, nil | ||
} | ||
|
||
func (dl *defaultLayer) SetDefault(k string, v interface{}) error { | ||
ka := strings.Split(k, dl.GetDelimiter()) | ||
return stringSetDefault(ka, v, dl.data) | ||
} | ||
|
||
// GetDelimiter return the delimiter for nested key | ||
func (dl defaultLayer) GetDelimiter() string { | ||
if dl.delimiter == "" { | ||
dl.delimiter = "." | ||
} | ||
|
||
return dl.delimiter | ||
} | ||
|
||
// SetDelimiter set the current delimiter | ||
func (dl *defaultLayer) SetDelimiter(d string) { | ||
dl.delimiter = d | ||
} | ||
|
||
// NewDefaultLayer is used to return a default layer. shoud load this layer | ||
// before any other layer, and before ading it, must add default value before | ||
// adding this layer to onion. | ||
func NewDefaultLayer() DefaultLayer { | ||
return &defaultLayer{".", make(map[string]interface{})} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package onion | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/smartystreets/goconvey/convey" | ||
) | ||
|
||
func TestDefaultLayer(t *testing.T) { | ||
Convey("Default layer basic test, some kind of coverage bitch :) ", t, func() { | ||
l := NewDefaultLayer() | ||
data, err := l.Load() | ||
So(err, ShouldBeNil) | ||
So(len(data), ShouldEqual, 0) | ||
|
||
err = l.SetDefault("layer1", 1) | ||
So(err, ShouldBeNil) | ||
err = l.SetDefault("layer1.layer2", 42) | ||
So(err, ShouldNotBeNil) | ||
|
||
err = l.SetDefault("p1.p2", true) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map", make(map[interface{}]interface{})) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map.in", "inside") | ||
So(err, ShouldBeNil) | ||
|
||
tmp := make(map[interface{}]interface{}) | ||
tmp["data"] = "data" | ||
|
||
tmp["map3"] = make(map[interface{}]interface{}) | ||
err = l.SetDefault("map.map2", tmp) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map.map2.another.int", 101) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map.map2.map3.int", 100) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map.map2.map3.int.other", 100) | ||
So(err, ShouldNotBeNil) | ||
|
||
tmp2 := make(map[string]interface{}) | ||
tmp2["data"] = "data" | ||
|
||
tmp2["map3"] = make(map[string]interface{}) | ||
err = l.SetDefault("map.map5", tmp2) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map.map5.map3.int", 100) | ||
So(err, ShouldBeNil) | ||
|
||
err = l.SetDefault("map.map5.map3.int.other", 100) | ||
So(err, ShouldNotBeNil) | ||
|
||
So(l.GetDelimiter(), ShouldEqual, ".") | ||
l.SetDelimiter("-") | ||
So(l.GetDelimiter(), ShouldEqual, "-") | ||
So(l.SetDefault("test-delim", 1), ShouldBeNil) | ||
l.SetDelimiter("") | ||
So(l.GetDelimiter(), ShouldEqual, ".") | ||
|
||
o := New() | ||
err = o.AddLayer(l) | ||
So(err, ShouldBeNil) | ||
|
||
So(o.GetInt("layer1"), ShouldEqual, 1) | ||
So(o.GetBool("p1.p2"), ShouldBeTrue) | ||
So(o.GetString("map.in"), ShouldEqual, "inside") | ||
So(o.GetString("map.map2.data"), ShouldEqual, "data") | ||
So(o.GetInt("map.map2.map3.int"), ShouldEqual, 100) | ||
So(o.GetInt("map.map2.another.int"), ShouldEqual, 101) | ||
So(o.GetInt("test.delim"), ShouldEqual, 1) | ||
}) | ||
} |
Oops, something went wrong.