支持嵌套结构体 #1
35
builder.go
35
builder.go
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user