支持嵌套结构体 #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 {
Field string
Builder Builder
JsonTag string
Tag string
}
builderImpl struct {
fields []*fieldConfigImpl
nestedStructTable map[string]nestedStruct // 嵌套结构体的定义, 父级路径 => 父级路径下挂接的子路径
maxFieldDeep int // 字段嵌套最大深度
structTagTable map[string]string // 字段路径 => json tag最高优先级, 没传的时候会使用AddField的tag, 也为空使用手搓json tag
}
fieldConfigImpl struct {
@ -71,10 +72,12 @@ type (
)
// NewStruct 获取builder实例
func NewStruct() Builder {
// 传入的tag映射表: 字段路径 => json tag最高优先级, 没传的时候会使用AddField的tag, 也为空使用手搓json tag
func NewStruct(structTagTable map[string]string) Builder {
return &builderImpl{
fields: []*fieldConfigImpl{},
nestedStructTable: make(map[string]nestedStruct),
structTagTable: structTagTable,
}
}
@ -85,7 +88,7 @@ func ExtendStruct(value ...any) Builder {
// MergeStructs 多个结构体合并成一个动态结构体
func MergeStructs(values ...any) Builder {
builder := NewStruct()
builder := NewStruct(map[string]string{})
for _, value := range values {
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 {
// 瞎话线转驼峰, 传入的name实际对应序列化时的json tag
// 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)
if !isNestedField {
@ -159,12 +169,16 @@ func (b *builderImpl) addNestedField(nameArr []string, pkg string, typ any, tag
parentName := strings.Join(nameArr[:i], ".")
parentJsonTag := nameArr[i-1]
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 _, exist := b.nestedStructTable[parentName]; !exist {
b.nestedStructTable[parentName] = nestedStruct{
Field: parentFieldName,
Builder: NewStruct(),
JsonTag: parentJsonTag,
Builder: NewStruct(b.structTagTable),
Tag: fieldTag,
}
}
}
@ -220,19 +234,12 @@ func (b *builderImpl) Build() DynamicStruct {
// 从深度最深处向上处理
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 {
// 说明是顶层了
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 {
// (非顶层) 父级结构存在, 将其追加到父级结构中即可, 向前看一步即为父级结构
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)
}
}
}