Merge pull request '支持Map类型的包装' (#6) from feature/support_map into master

Reviewed-on: #6
This commit is contained in:
白茶清欢 2024-11-19 16:31:04 +08:00
commit cfdb588156
4 changed files with 334 additions and 62 deletions

View File

@ -7,7 +7,10 @@
// Date : 2023-05-05 14:44 // Date : 2023-05-05 14:44
package wrapper package wrapper
import "time" import (
"git.zhangdeman.cn/zhangdeman/easymap"
"time"
)
// Int8Result ... // Int8Result ...
// //
@ -465,7 +468,7 @@ type StringSliceResult struct {
// //
// Date : 16:05 2023/8/10 // Date : 16:05 2023/8/10
type MapResult struct { type MapResult struct {
Value Map Value easymap.EasyMap
Err error Err error
} }

88
easymap.go Normal file
View File

@ -0,0 +1,88 @@
// Package wrapper ...
//
// Description : wrapper ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2023-08-10 15:01
package wrapper
import (
"encoding/json"
"errors"
"git.zhangdeman.cn/zhangdeman/easymap"
"git.zhangdeman.cn/zhangdeman/serialize"
"github.com/tidwall/gjson"
"reflect"
)
// EasyMap ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:02 2023/8/10
func EasyMap(mapData any) easymap.EasyMap {
m, _ := EasyMapWithError(mapData)
return m
}
// EasyMapWithError 转换map并带上转换的异常
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:06 2023/8/10
func EasyMapWithError(mapData any) (easymap.EasyMap, error) {
if nil == mapData {
return easymap.NewNormal(), nil
}
m := easymap.NewNormal()
reflectType := reflect.TypeOf(mapData)
if reflectType.Kind() != reflect.Map {
mapFormatData := make(map[string]any)
if err := serialize.JSON.UnmarshalWithNumber(serialize.JSON.MarshalForByteIgnoreError(mapData), &mapFormatData); nil != err {
return m, errors.New("input data type is " + reflectType.String() + ", can not convert to map")
}
mapData = mapFormatData
}
reflectValue := reflect.ValueOf(mapData).MapRange()
for reflectValue.Next() {
// 循环提取相关值
m.Set(reflectValue.Key().Interface(), reflectValue.Value().Interface())
}
return m, nil
}
// EasyMapFromStruct 从struct转map
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:11 2023/8/10
func EasyMapFromStruct(data any) easymap.EasyMap {
byteData, _ := json.Marshal(data)
return EasyMapFromByte(byteData)
}
// EasyMapFromString 从string转为Map
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:12 2023/8/10
func EasyMapFromString(data string) easymap.EasyMap {
return EasyMapFromByte([]byte(data))
}
// EasyMapFromByte 从字节数组转为Map
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:12 2023/8/10
func EasyMapFromByte(data []byte) easymap.EasyMap {
res := easymap.NewNormal()
jsonRes := gjson.Parse(string(data))
jsonRes.ForEach(func(key, value gjson.Result) bool {
res.Set(key.Value(), value.Value())
return true
})
return res
}

254
map.go
View File

@ -4,92 +4,226 @@
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 2023-08-10 15:01 // Date : 2024-11-06 18:27
package wrapper package wrapper
import ( import (
"encoding/json"
"errors" "errors"
"git.zhangdeman.cn/zhangdeman/easymap"
"git.zhangdeman.cn/zhangdeman/serialize" "git.zhangdeman.cn/zhangdeman/serialize"
"github.com/tidwall/gjson"
"reflect" "reflect"
"sync"
) )
// EasyMap ... var mapLock = &sync.RWMutex{}
//
// Author : go_developer@163.com<白茶清欢> type Map map[string]any
//
// Date : 15:02 2023/8/10 func (m *Map) lock() {
func EasyMap(mapData any) Map { mapLock.Lock()
m, _ := EasyMapWithError(mapData)
return m
} }
// EasyMapWithError 转换map并带上转换的异常 func (m *Map) unlock() {
mapLock.Unlock()
}
func (m *Map) rLock() {
mapLock.RLock()
}
func (m *Map) rUnlock() {
mapLock.RUnlock()
}
// Exist key是否存在
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 15:06 2023/8/10 // Date : 18:34 2024/11/6
func EasyMapWithError(mapData any) (Map, error) { func (m *Map) Exist(key string) bool {
if nil == mapData { if m.IsNil() {
return easymap.NewNormal(), nil return false
} }
m := easymap.NewNormal() m.rLock()
reflectType := reflect.TypeOf(mapData) defer m.rUnlock()
if reflectType.Kind() != reflect.Map { v := *m
mapFormatData := make(map[string]any) _, exist := v[key]
if err := serialize.JSON.UnmarshalWithNumber(serialize.JSON.MarshalForByteIgnoreError(mapData), &mapFormatData); nil != err { return exist
return m, errors.New("input data type is " + reflectType.String() + ", can not convert to map") }
}
mapData = mapFormatData // Set 设置map的值, 字段如果已存在, 会覆盖
//
// 参数说明:
// - field : 摇摆存的字段
// - value : 字段对应的值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:16 2024/11/19
func (m *Map) Set(field string, value any) error {
if m.IsNil() {
return errors.New("Map is nil")
} }
m.lock()
defer m.unlock()
(*m)[field] = value
return nil
}
reflectValue := reflect.ValueOf(mapData).MapRange() // Del 删除指定的字段
for reflectValue.Next() { //
// 循环提取相关值 // Author : go_developer@163.com<白茶清欢>
m.Set(reflectValue.Key().Interface(), reflectValue.Value().Interface()) //
// Date : 15:21 2024/11/19
func (m *Map) Del(field string) {
if m.IsNil() {
return
} }
return m, nil m.lock()
defer m.unlock()
delete(*m, field)
} }
// EasyMapFromStruct 从struct转map // IsNil 判断map是否为nil
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 16:11 2023/8/10 // Date : 15:22 2024/11/19
func EasyMapFromStruct(data any) Map { func (m *Map) IsNil() bool {
byteData, _ := json.Marshal(data) if nil == m {
return EasyMapFromByte(byteData)
}
// EasyMapFromString 从string转为Map
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:12 2023/8/10
func EasyMapFromString(data string) Map {
return EasyMapFromByte([]byte(data))
}
// EasyMapFromByte 从字节数组转为Map
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:12 2023/8/10
func EasyMapFromByte(data []byte) Map {
res := easymap.NewNormal()
jsonRes := gjson.Parse(string(data))
jsonRes.ForEach(func(key, value gjson.Result) bool {
res.Set(key.Value(), value.Value())
return true return true
}) }
return reflect.ValueOf(*m).IsNil()
}
// Get ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:41 2024/11/19
func (m *Map) Get(field string) (any, error) {
if m.IsNil() {
return nil, errors.New("map is nil")
}
m.rLock()
defer m.rUnlock()
v := *m
val, exist := v[field]
if !exist {
return nil, errors.New(field + " : field not found")
}
return val, nil
}
// GetDefault 获取指定字段, 不存在则设置默认值
//
// 参数说明:
// - field : 要读取的字段
// - defaultValue : 字段不存在返回的默认值
// - allowNil : 字段存在, 但是值为Nil, 是否是一个合法值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:59 2024/11/19
func (m *Map) GetDefault(field string, defaultValue any, allowNil bool) any {
if m.IsNil() {
return defaultValue
}
m.rLock()
defer m.rUnlock()
v := *m
val, exist := v[field]
if !exist {
return defaultValue
}
if nil == val {
if allowNil {
return val
}
return defaultValue
}
return val
}
// Value 获取数据值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 19:39 2024/11/6
func (m *Map) Value() map[string]any {
if m.IsNil() {
return nil
}
return *m
}
// Clone 克隆数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 19:40 2024/11/6
func (m *Map) Clone() Map {
newData := map[string]any{}
if m.IsNil() {
return newData
}
m.rLock()
defer m.rUnlock()
mapValue := m.Value()
for k, v := range mapValue {
newData[k] = v
}
return newData
}
// Filter 过滤指定字段
//
// 参数说明:
// - fieldList : 要保留的字段列表
// - ignoreNotFound : 指定字段不存在是否忽略,如不忽略, 字段不存在, 将会报错
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:40 2024/11/19
func (m *Map) Filter(fieldList []string, ignoreNotFound bool) (map[string]any, error) {
res := make(map[string]any)
for _, itemField := range fieldList {
if val, err := m.Get(itemField); err == nil {
res[itemField] = val
} else {
if !ignoreNotFound {
return nil, err
}
}
}
return res, nil
}
// FilterDefault 过滤指定字段, 字段不存储在则用默认值填充
//
// 参数说明:
// - fieldMap : 查询字段表, key为要查询的字段, value为 字段不存在时返回的默认值
// - allowNil : 字段存在, 三只值为你来是否是一个合法值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:07 2024/11/19
func (m *Map) FilterDefault(fieldMap map[string]any, allowNil bool) map[string]any {
res := make(map[string]any)
for itemField, fieldDefaultValue := range fieldMap {
res[itemField] = m.GetDefault(itemField, fieldDefaultValue, allowNil)
}
return res return res
} }
// Map ... // MarshalJSON Map序列化
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 15:14 2023/8/10 // Date : 15:35 2024/11/19
type Map easymap.EasyMap func (m *Map) MarshalJSON() ([]byte, error) {
mapData := m.Value()
if nil == mapData {
return nil, nil
}
return serialize.JSON.MarshalForByte(mapData)
}

47
map_test.go Normal file
View File

@ -0,0 +1,47 @@
// Package wrapper ...
//
// Description : wrapper ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-11-06 18:37
package wrapper
import (
"fmt"
"testing"
)
func TestMap_Exist(t *testing.T) {
testData := Map(map[string]any{
"name": "zhang",
})
fmt.Println(testData.Exist("name"))
fmt.Println(testData.Exist("age"))
}
func TestMap_IsNil(t *testing.T) {
var (
m Map
m1 *Map
)
fmt.Println(m.Set("a", 1))
fmt.Println(m.IsNil(), m1.IsNil())
}
func TestMap_IsMasher(t *testing.T) {
var (
m Map
m1 = Map(map[string]any{
"a": 1,
"b": m,
"c": Map(map[string]any{
"name": "de",
}),
})
)
d, err := m.MarshalJSON()
fmt.Println(string(d), err)
d, err = m1.MarshalJSON()
fmt.Println(string(d), err)
}