diff --git a/structs/alias.go b/structs/alias.go index 528805611..a25e1bf09 100644 --- a/structs/alias.go +++ b/structs/alias.go @@ -27,7 +27,6 @@ func (as *Aliases) AddAlias(real, alias string) { if rn, ok := as.mapping[alias]; ok { panic(fmt.Sprintf("The alias '%s' is already used by '%s'", alias, rn)) } - as.mapping[alias] = real } diff --git a/structs/alias_test.go b/structs/alias_test.go index 015655d01..a007e1c36 100644 --- a/structs/alias_test.go +++ b/structs/alias_test.go @@ -25,6 +25,8 @@ func TestAliases_AddAliases(t *testing.T) { assert.Eq(t, "real1", as.ResolveAlias("a1")) assert.Eq(t, "notExist", as.ResolveAlias("notExist")) + assert.NotEmpty(t, as.Mapping()) + assert.PanicsMsg(t, func() { as.AddAlias("real3", "a") }, "The alias 'a' is already used by 'real'") diff --git a/structs/data.go b/structs/data.go index ae0081898..9dbe09845 100644 --- a/structs/data.go +++ b/structs/data.go @@ -10,76 +10,47 @@ import ( ) // LiteData simple map[string]any struct. no lock -type LiteData struct { - data map[string]any -} - -// Data get all -func (d *LiteData) Data() map[string]any { - return d.data -} - -// SetData set all data -func (d *LiteData) SetData(data map[string]any) { - d.data = data -} - -// Value get from data -func (d *LiteData) Value(key string) any { - return d.data[key] -} - -// GetVal get from data -func (d *LiteData) GetVal(key string) any { - return d.data[key] -} +type LiteData = Data -// StrValue get from data -func (d *LiteData) StrValue(key string) string { - return strutil.QuietString(d.data[key]) -} - -// IntVal get from data -func (d *LiteData) IntVal(key string) int { - return mathutil.QuietInt(d.data[key]) -} - -// SetValue to data -func (d *LiteData) SetValue(key string, val any) { - if d.data == nil { - d.data = make(map[string]any) +// NewLiteData create, not lock +func NewLiteData(data map[string]any) *Data { + if data == nil { + data = make(map[string]any) } - d.data[key] = val -} -// ResetData all data -func (d *LiteData) ResetData() { - d.data = nil + return &LiteData{ + data: data, + } } /************************************************************* * data struct and allow enable lock *************************************************************/ -// Data struct, allow enable lock TODO +// Data struct, allow enable lock type Data struct { sync.RWMutex - enableLock bool - // data store + lock bool data map[string]any } -// NewData create +// NewData create new data instance func NewData() *Data { return &Data{ + lock: true, data: make(map[string]any), } } +// WithLock for operate data +func (d *Data) WithLock() *Data { + d.lock = true + return d +} + // EnableLock for operate data func (d *Data) EnableLock() *Data { - d.enableLock = true - return d + return d.WithLock() } // Data get all @@ -89,7 +60,7 @@ func (d *Data) Data() map[string]any { // SetData set all data func (d *Data) SetData(data map[string]any) { - if !d.enableLock { + if !d.lock { d.data = data return } @@ -109,6 +80,11 @@ func (d *Data) ResetData() { d.data = make(map[string]any) } +// Merge load new data +func (d *Data) Merge(mp map[string]any) { + d.data = maputil.SimpleMerge(d.data, mp) +} + // Set value to data func (d *Data) Set(key string, val any) { d.SetValue(key, val) @@ -116,7 +92,7 @@ func (d *Data) Set(key string, val any) { // SetValue to data func (d *Data) SetValue(key string, val any) { - if d.enableLock { + if d.lock { d.Lock() defer d.Unlock() } @@ -126,12 +102,12 @@ func (d *Data) SetValue(key string, val any) { // Value get from data func (d *Data) Value(key string) (val any, ok bool) { - if d.enableLock { + if d.lock { d.RLock() defer d.RUnlock() } - val, ok = d.data[key] + val, ok = maputil.GetByPath(key, d.data) return } @@ -142,12 +118,13 @@ func (d *Data) Get(key string) any { // GetVal get from data func (d *Data) GetVal(key string) any { - if d.enableLock { + if d.lock { d.RLock() defer d.RUnlock() } - return d.data[key] + val, _ := maputil.GetByPath(key, d.data) + return val } // StrVal get from data diff --git a/structs/data_test.go b/structs/data_test.go index 9236b630a..540ff7565 100644 --- a/structs/data_test.go +++ b/structs/data_test.go @@ -7,16 +7,41 @@ import ( "github.com/gookit/goutil/testutil/assert" ) +func TestLiteData_Data(t *testing.T) { + d := structs.NewLiteData(nil) + d.SetData(map[string]any{ + "key0": 234, + "key1": "abc", + "key2": true, + }) + + assert.NotEmpty(t, d.Data()) + v, ok := d.Value("key0") + assert.True(t, ok) + assert.Eq(t, 234, v) + + d.ResetData() + assert.Empty(t, d.Data()) +} + func TestNewData(t *testing.T) { md := structs.NewData() assert.Eq(t, 0, md.DataLen()) md.SetData(map[string]any{ "key0": 234, + "sub": map[string]any{ + "skey1": "abc", + "skey2": true, + }, }) assert.NotEmpty(t, md.Data()) assert.Eq(t, 234, md.IntVal("key0")) + v, ok := md.Value("key0") + assert.True(t, ok) + assert.Eq(t, 234, v) + md.SetValue("key1", "val1") assert.Eq(t, "val1", md.GetVal("key1")) assert.Eq(t, "val1", md.StrVal("key1"))