这个库是一个把结构体转换为map的库,不支持标签
go// KeyCase 表示输出键的大小写规范
type KeyCase int
const (
NotSet KeyCase = iota // 不设置规范
CamelCase // 驼峰命名法
PascalCase // 帕斯卡命名法
SnakeCase // 蛇形命名法
)
var defaultCase = NotSet // 默认规范为不设置
// SetDefaultCase 用于设置默认的键规范
func SetDefaultCase(caseType KeyCase) {
defaultCase = caseType
}
type mapModifier func(jsonMap) jsonMap
type jsonMap map[string]interface{}
// Predicate 是 func(interface{}) bool 的别名,用于测试是否包含某个字段
type Predicate func(interface{}) bool
// KeyConverter 是 func(string) string 的别名,用于转换键的名称
type KeyConverter func(string) string
// ValueConverter 是 func(interface{}) interface{} 的别名,用于转换值
type ValueConverter func(interface{}) interface{}
// Serializer 是所有序列化方法的基础接口
type Serializer interface {
Transform(entity interface{}) map[string]interface{}
TransformArray(entities interface{}) ([]map[string]interface{}, error)
MustTransformArray(entities interface{}) []map[string]interface{}
ConvertKeys(keyConverter KeyConverter) Serializer
UseSnakeCase() Serializer
UseCamelCase() Serializer
UsePascalCase() Serializer
PickAll() Serializer
Pick(keys ...string) Serializer
PickIf(predicate Predicate, keys ...string) Serializer
PickFunc(converter ValueConverter, keys ...string) Serializer
PickFuncIf(predicate Predicate, converter ValueConverter, keys ...string) Serializer
Omit(keys ...string) Serializer
OmitIf(predicate Predicate, keys ...string) Serializer
Add(key string, value interface{}) Serializer
AddIf(predicate Predicate, key string, value interface{}) Serializer
AddFunc(key string, converter ValueConverter) Serializer
AddFuncIf(predicate Predicate, key string, converter ValueConverter) Serializer
}
这里定义了一系列类型,包括 KeyCase
枚举类型、mapModifier
函数类型和别名类型 jsonMap
、Predicate
、KeyConverter
、ValueConverter
以及 Serializer
接口。
gofunc alwaysTrue(u interface{}) bool {
return true
}
func alwaysFalse(u interface{}) bool {
return false
}
func identity(u interface{}) interface{} {
return u
}
这里定义了三个用于作为默认参数的函数,alwaysTrue
总是返回 true
,alwaysFalse
总是返回 false
,identity
返回输入参数本身。
gotype Base struct {
raw interface{}
modifiers []mapModifier
reflected reflect.Value
keyConverter KeyConverter
}
func New() *Base {
b := &Base{}
b.addDefaultKeyConverter()
return b
}
Base
结构体是 Serializer
接口的基础实现,包含了原始数据 raw
、一系列修改器函数 modifiers
、反射得到的值 reflected
和键转换函数 keyConverter
。
New
函数返回一个新的 Base
实例,并调用 addDefaultKeyConverter
设置默认键转换函数。
gofunc (b *Base) Transform(entity interface{}) map[string]interface{} {
b.raw = entity
b.reflected = reflect.Indirect(reflect.ValueOf(entity))
return b.result()
}
Transform
方法将实体转换为 map[string]interface{}
,并设置 raw
和 reflected
属性。
gofunc (b *Base) TransformArray(entities interface{}) ([]map[string]interface{}, error) {
s := reflect.ValueOf(entities)
if s.Kind() != reflect.Slice && s.Kind() != reflect.Array {
return nil, fmt.Errorf("TransformArray() given a non-slice type")
}
result := []map[string]interface{}{}
for i := 0; i < s.Len(); i++ {
result = append(result, b.Transform(s.Index(i).Interface()))
}
return result, nil
}
func (b *Base) MustTransformArray(entities interface{}) []map[string]interface{} {
res, err := b.TransformArray(entities)
if err != nil {
panic(err)
}
return res
}
TransformArray
方法将实体数组转换为 []map[string]interface{}
,并对输入类型进行检查。MustTransformArray
方法在 TransformArray
的基础上增加了 panic 处理。
gofunc (
b *Base) addDefaultKeyConverter() {
switch defaultCase {
case PascalCase:
b.UsePascalCase()
case SnakeCase:
b.UseSnakeCase()
case CamelCase:
b.UseCamelCase()
default:
break
}
}
func (b *Base) transformedResult(result jsonMap) jsonMap {
newResult := make(map[string]interface{})
for key, value := range result {
newResult[b.keyConverter(key)] = value
}
return newResult
}
func (b *Base) result() map[string]interface{} {
result := make(map[string]interface{})
for _, modifier := range b.modifiers {
result = modifier(result)
}
if b.keyConverter != nil {
return b.transformedResult(result)
}
return result
}
addDefaultKeyConverter
方法根据默认键规范设置键转换函数。
transformedResult
方法使用键转换函数对结果进行转换。
result
方法应用所有修改器函数,并根据键转换函数进行最终结果的转换。
gofunc (b *Base) ConvertKeys(keyConverter KeyConverter) Serializer {
b.keyConverter = keyConverter
return b
}
func (b *Base) UsePascalCase() Serializer {
return b.ConvertKeys(func(k string) string {
return xstrings.ToCamelCase(xstrings.ToSnakeCase(k))
})
}
func (b *Base) UseCamelCase() Serializer {
return b.ConvertKeys(func(k string) string {
return xstrings.FirstRuneToLower(xstrings.ToCamelCase(xstrings.ToSnakeCase(k)))
})
}
func (b *Base) UseSnakeCase() Serializer {
return b.ConvertKeys(xstrings.ToSnakeCase)
}
ConvertKeys
方法用于设置键转换函数,UsePascalCase
、UseCamelCase
、UseSnakeCase
方法分别设置不同的键规范。
gofunc (b *Base) PickAll() Serializer {
b.modifiers = append(b.modifiers, func(m jsonMap) jsonMap {
return structs.Map(b.raw)
})
return b
}
func (b *Base) Pick(keys ...string) Serializer {
return b.PickFunc(identity, keys...)
}
func (b *Base) PickIf(p Predicate, keys ...string) Serializer {
return b.PickFuncIf(p, identity, keys...)
}
func (b *Base) PickFunc(converter ValueConverter, keys ...string) Serializer {
return b.PickFuncIf(alwaysTrue, converter, keys...)
}
func (b *Base) PickFuncIf(p Predicate, converter ValueConverter, keys ...string) Serializer {
b.modifiers = append(b.modifiers, func(m jsonMap) jsonMap {
if p(b.raw) {
for _, key := range keys {
m[key] = converter(b.reflected.FieldByName(key).Interface())
}
}
return m
})
return b
}
PickAll
方法将所有公开字段添加到结果中。
Pick
方法添加指定字段到结果。
PickIf
方法添加指定字段到结果,仅当 Predicate 返回 true
时。
PickFunc
方法添加通过 ValueConverter 转换后的指定字段到结果。
PickFuncIf
方法添加通过 ValueConverter 转换后的指定字段到结果,仅当 Predicate 返回 true
时。
gofunc (b *Base) Omit(keys ...string) Serializer {
return b.OmitIf(alwaysTrue, keys...)
}
func (b *Base) OmitIf(p Predicate, keys ...string) Serializer {
b.modifiers = append(b.modifiers, func(m jsonMap) jsonMap {
if p(b.raw) {
for _, key := range keys {
delete(m, key)
}
}
return m
})
return b
}
Omit
方法从结果中排除指定字段。
OmitIf
方法从结果中排除指定字段,仅当 Predicate 返回 true
时。
gofunc (b *Base) Add(key string, value interface{}) Serializer {
return b.AddIf(alwaysTrue, key, value)
}
func (b *Base) AddIf(p Predicate, key string, value interface{}) Serializer {
return b.AddFuncIf(p, key, func(m interface{}) interface{} { return value })
}
func (b *Base) AddFunc(key string, f ValueConverter) Serializer {
return b.AddFuncIf(alwaysTrue, key, f)
}
func (b *Base) AddFuncIf(p Predicate, key string, f ValueConverter) Serializer {
b.modifiers = append(b.modifiers, func(m jsonMap) jsonMap {
if p(b.raw) {
m[key] = f(b.raw)
}
return m
})
return b
}
Add
方法向结果中添加指定的自定义字段。
AddIf
方法向结果中添加指定的自定义字段,仅当 Predicate 返回 true
时。
AddFunc
方法向结果中添加通过 ValueConverter 转换后的自定义字段。
AddFuncIf
方法向结果中添加通过 ValueConverter 转换后的自定义字段,仅当 Predicate 返回 true
时。
这些方法允许用户添加自定义字段到结果中。
KeyCase 枚举类型: 定义了表示键的命名规则的枚举类型,包括 NotSet(未设置)、CamelCase(驼峰命名法)、PascalCase(帕斯卡命名法)、SnakeCase(蛇形命名法)。
mapModifier 函数类型: 用于修改输出的 map
的函数类型。
jsonMap 类型: map[string]interface{}
的别名,用于表示 JSON 对象。
Predicate、KeyConverter、ValueConverter 函数类型: 分别用于测试字段是否包含、转换键的名称、转换字段的值。
Serializer 接口: 定义了所有序列化方法的接口。
Base 结构体: 实现了 Serializer 接口的基础结构,包括对键的默认转换和一些常见的转换操作。
New 函数: 创建一个新的 Serializer 实例。
Transform 方法: 将实体(结构体)转换为 map[string]interface{}
。
TransformArray 方法: 将实体数组(切片)转换为 []map[string]interface{}
。
MustTransformArray 方法: 与 TransformArray 相同,但如果发生错误则引发 panic。
ConvertKeys 方法: 设置键的命名规则。
UsePascalCase、UseCamelCase、UseSnakeCase 方法: 设置键的命名规则为帕斯卡命名法、驼峰命名法、蛇形命名法。
PickAll 方法: 添加所有导出字段到结果。
Pick 方法: 添加指定的字段到结果。
PickIf 方法: 如果满足条件,则添加指定的字段到结果。
PickFunc 方法: 使用转换函数,添加指定的字段到结果。
PickFuncIf 方法: 如果满足条件,则使用转换函数,添加指定的字段到结果。
Omit 方法: 从结果中省略指定的字段。
OmitIf 方法: 如果满足条件,则从结果中省略指定的字段。
Add 方法: 添加自定义字段到结果。
AddIf 方法: 如果满足条件,则添加自定义字段到结果。
AddFunc 方法: 使用转换函数,添加计算的自定义字段到结果。
AddFuncIf 方法: 如果满足条件,则使用转换函数,添加计算的自定义字段到结果。
goserializer := structomap.New().UseSnakeCase().Pick("FieldName").Add("CustomField", "some value")
result := serializer.Transform(someStruct)
在上述示例中,创建了一个新的 structomap
实例,设置了键的命名规则为蛇形命名法,然后选择了结构体中名为 "FieldName" 的字段,添加了一个自定义字段 "CustomField" 到结果中,最后进行了转换。
这个库的设计允许用户根据需要选择转换的方式,非常适用于将结构体数据转换为 JSON 对象的场景。
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!