这个库是一个把结构体转换为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 许可协议。转载请注明出处!