支持嵌套结构体 #1

Merged
zhangdeman merged 6 commits from feture/nested_struct into master 2025-03-21 23:43:27 +08:00
Showing only changes of commit 38c706ee7b - Show all commits

View File

@ -47,13 +47,14 @@ type (
nestedStruct struct { nestedStruct struct {
Field string Field string
Builder Builder Builder Builder
JsonTag string Tag string
} }
builderImpl struct { builderImpl struct {
fields []*fieldConfigImpl fields []*fieldConfigImpl
nestedStructTable map[string]nestedStruct // 嵌套结构体的定义, 父级路径 => 父级路径下挂接的子路径 nestedStructTable map[string]nestedStruct // 嵌套结构体的定义, 父级路径 => 父级路径下挂接的子路径
maxFieldDeep int // 字段嵌套最大深度 maxFieldDeep int // 字段嵌套最大深度
structTagTable map[string]string // 字段路径 => json tag最高优先级, 没传的时候会使用AddField的tag, 也为空使用手搓json tag
} }
fieldConfigImpl struct { fieldConfigImpl struct {
@ -71,10 +72,12 @@ type (
) )
// NewStruct 获取builder实例 // NewStruct 获取builder实例
func NewStruct() Builder { // 传入的tag映射表: 字段路径 => json tag最高优先级, 没传的时候会使用AddField的tag, 也为空使用手搓json tag
func NewStruct(structTagTable map[string]string) Builder {
return &builderImpl{ return &builderImpl{
fields: []*fieldConfigImpl{}, fields: []*fieldConfigImpl{},
nestedStructTable: make(map[string]nestedStruct), nestedStructTable: make(map[string]nestedStruct),
structTagTable: structTagTable,
} }
} }
@ -85,7 +88,7 @@ func ExtendStruct(value ...any) Builder {
// MergeStructs 多个结构体合并成一个动态结构体 // MergeStructs 多个结构体合并成一个动态结构体
func MergeStructs(values ...any) Builder { func MergeStructs(values ...any) Builder {
builder := NewStruct() builder := NewStruct(map[string]string{})
for _, value := range values { for _, value := range values {
valueOf := reflect.Indirect(reflect.ValueOf(value)) valueOf := reflect.Indirect(reflect.ValueOf(value))
@ -111,6 +114,13 @@ func (b *builderImpl) parseNestedField(fieldName string) ([]string, bool) {
func (b *builderImpl) AddField(name string, pkg string, typ any, tag string, anonymous bool) Builder { func (b *builderImpl) AddField(name string, pkg string, typ any, tag string, anonymous bool) Builder {
// 瞎话线转驼峰, 传入的name实际对应序列化时的json tag // 瞎话线转驼峰, 传入的name实际对应序列化时的json tag
// name = wrapper.String(name).SnakeCaseToCamel() // name = wrapper.String(name).SnakeCaseToCamel()
if cfgTag, exist := b.structTagTable[name]; exist && len(cfgTag) > 0 {
tag = cfgTag
} else {
if len(tag) == 0 {
tag = fmt.Sprintf(`json:"%s"`, name)
}
}
// 判断是否嵌套结构体 // 判断是否嵌套结构体
fieldNameArr, isNestedField := b.parseNestedField(name) fieldNameArr, isNestedField := b.parseNestedField(name)
if !isNestedField { if !isNestedField {
@ -159,12 +169,16 @@ func (b *builderImpl) addNestedField(nameArr []string, pkg string, typ any, tag
parentName := strings.Join(nameArr[:i], ".") parentName := strings.Join(nameArr[:i], ".")
parentJsonTag := nameArr[i-1] parentJsonTag := nameArr[i-1]
parentFieldName := wrapper.String(parentJsonTag).SnakeCaseToCamel() parentFieldName := wrapper.String(parentJsonTag).SnakeCaseToCamel()
fieldTag := fmt.Sprintf(`json:"%s"`, parentJsonTag)
if tagCfg, exist := b.structTagTable[parentName]; exist && len(tagCfg) > 0 {
fieldTag = tagCfg
}
if len(parentName) > 0 { if len(parentName) > 0 {
if _, exist := b.nestedStructTable[parentName]; !exist { if _, exist := b.nestedStructTable[parentName]; !exist {
b.nestedStructTable[parentName] = nestedStruct{ b.nestedStructTable[parentName] = nestedStruct{
Field: parentFieldName, Field: parentFieldName,
Builder: NewStruct(), Builder: NewStruct(b.structTagTable),
JsonTag: parentJsonTag, Tag: fieldTag,
} }
} }
} }
@ -220,19 +234,12 @@ func (b *builderImpl) Build() DynamicStruct {
// 从深度最深处向上处理 // 从深度最深处向上处理
continue continue
} }
/*if deep == b.maxFieldDeep-1 {
// 说明最深层嵌套结构
parentJsonTag := parentNameArr[deep-1]
parentField := wrapper.String(parentJsonTag).SnakeCaseToCamel()
b.AddField(parentField, "", builderCfg.Builder.Build().New(), fmt.Sprintf(`json:"%v"`, parentJsonTag), false)
continue
}*/
if deep == 1 { if deep == 1 {
// 说明是顶层了 // 说明是顶层了
b.AddField(builderCfg.Field, "", builderCfg.Builder.Build().New(), fmt.Sprintf(`json:"%v"`, builderCfg.JsonTag), false) b.AddField(builderCfg.Field, "", builderCfg.Builder.Build().New(), builderCfg.Tag, false)
} else { } else {
// (非顶层) 父级结构存在, 将其追加到父级结构中即可, 向前看一步即为父级结构 // (非顶层) 父级结构存在, 将其追加到父级结构中即可, 向前看一步即为父级结构
b.nestedStructTable[strings.Join(parentNameArr[:len(parentNameArr)-1], ".")].Builder.AddField(builderCfg.Field, "", builderCfg.Builder.Build().New(), fmt.Sprintf(`json:"%v"`, builderCfg.JsonTag), false) b.nestedStructTable[strings.Join(parentNameArr[:len(parentNameArr)-1], ".")].Builder.AddField(builderCfg.Field, "", builderCfg.Builder.Build().New(), builderCfg.Tag, false)
} }
} }
} }