Merge pull request '运行时动态结构体支持数组!!!!!!!!' (#2) from feature/support_arr into master
Reviewed-on: #2
This commit is contained in:
commit
7b830c8a9e
43
builder.go
43
builder.go
@ -238,14 +238,52 @@ func (b *builderImpl) Build() DynamicStruct {
|
|||||||
// 说明是顶层了
|
// 说明是顶层了
|
||||||
b.AddField(builderCfg.Field, "", builderCfg.Builder.Build().New(), builderCfg.Tag, 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(), builderCfg.Tag, false)
|
arrDeep := 0
|
||||||
|
newParentNameArr := []string{}
|
||||||
|
for i := len(parentNameArr) - 1; i >= 0; i-- {
|
||||||
|
if parentNameArr[i] != ArraySplit {
|
||||||
|
newParentNameArr = parentNameArr[:i+1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
delete(b.nestedStructTable, strings.Join(parentNameArr[:i+1], "."))
|
||||||
|
arrDeep++
|
||||||
|
}
|
||||||
|
if arrDeep > 0 {
|
||||||
|
// 数组嵌套数组配置
|
||||||
|
val := reflect.ValueOf(builderCfg.Builder.Build().New()).Elem().Interface()
|
||||||
|
for i := 0; i < arrDeep; i++ {
|
||||||
|
val = reflect.New(reflect.SliceOf(reflect.TypeOf(val))).Interface()
|
||||||
|
}
|
||||||
|
// 解除指针引用
|
||||||
|
val = reflect.ValueOf(val).Elem().Interface()
|
||||||
|
newParamIndex := strings.Join(newParentNameArr, ".")
|
||||||
|
isTopIndex := len(newParentNameArr) == 1
|
||||||
|
if isTopIndex {
|
||||||
|
// 顶层结构, 数组类型不存在还有其他属性情况, 直接追加字段, 并移除嵌套表里的定义
|
||||||
|
b.AddField(b.nestedStructTable[newParamIndex].Field, "", val, b.nestedStructTable[newParamIndex].Tag, false)
|
||||||
|
delete(b.nestedStructTable, newParamIndex)
|
||||||
|
// b.nestedStructTable[newParamIndex].Builder.AddField(b.nestedStructTable[newParamIndex].Field, "", val, b.nestedStructTable[newParamIndex].Tag, false)
|
||||||
|
} else {
|
||||||
|
// 非顶层结构, 再上探一级
|
||||||
|
b.nestedStructTable[strings.Join(newParentNameArr[:len(newParentNameArr)-1], ".")].Builder.AddField(b.nestedStructTable[newParamIndex].Field, "", val, b.nestedStructTable[newParamIndex].Tag, false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非数组
|
||||||
|
// (非顶层) 父级结构存在, 将其追加到父级结构中即可, 向前看一步即为父级结构
|
||||||
|
b.nestedStructTable[strings.Join(parentNameArr[:len(parentNameArr)-1], ".")].Builder.AddField(builderCfg.Field, "", builderCfg.Builder.Build().New(), builderCfg.Tag, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 一级字段属性
|
// 一级字段属性
|
||||||
var structFields []reflect.StructField
|
var structFields []reflect.StructField
|
||||||
for _, field := range b.fields {
|
for _, field := range b.fields {
|
||||||
|
if strings.Contains(field.name, ArraySplit) {
|
||||||
|
// TODO : 临时过滤, 后续需要在正确逻辑处正确移除
|
||||||
|
continue
|
||||||
|
}
|
||||||
structFields = append(structFields, reflect.StructField{
|
structFields = append(structFields, reflect.StructField{
|
||||||
Name: field.name,
|
Name: field.name,
|
||||||
PkgPath: field.pkg,
|
PkgPath: field.pkg,
|
||||||
@ -274,6 +312,7 @@ func (f *fieldConfigImpl) SetTag(tag string) FieldConfig {
|
|||||||
|
|
||||||
// New 创建动态结构体实例
|
// New 创建动态结构体实例
|
||||||
func (ds *dynamicStructImpl) New() any {
|
func (ds *dynamicStructImpl) New() any {
|
||||||
|
// 不要指针,全部解引用
|
||||||
return reflect.New(ds.definition).Interface()
|
return reflect.New(ds.definition).Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,12 @@ package dynamicstruct
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_dynamicStructImpl_New(t *testing.T) {
|
func Test_dynamicStructImpl_New(t *testing.T) {
|
||||||
instance := NewStruct().
|
instance := NewStruct(map[string]string{}).
|
||||||
/*AddField("Integer", "", 0, `json:"int"`, false).
|
/*AddField("Integer", "", 0, `json:"int"`, false).
|
||||||
AddField("Text", "", "", `json:"someText"`, false).
|
AddField("Text", "", "", `json:"someText"`, false).
|
||||||
AddField("Float", "", 0.0, `json:"double"`, false).
|
AddField("Float", "", 0.0, `json:"double"`, false).
|
||||||
@ -25,10 +26,11 @@ func Test_dynamicStructImpl_New(t *testing.T) {
|
|||||||
AddField("user.base.name", "", "", `json:"name"`, false).
|
AddField("user.base.name", "", "", `json:"name"`, false).
|
||||||
AddField("user.job.address", "", "", `json:"address"`, false).
|
AddField("user.job.address", "", "", `json:"address"`, false).
|
||||||
AddField("user.job.company.name", "", "", `json:"name"`, false).
|
AddField("user.job.company.name", "", "", `json:"name"`, false).
|
||||||
|
AddField("arr.[].item.name", "", "", `json:"name"`, false).
|
||||||
|
AddField("arr2.[].[].item.name", "", "", `json:"name"`, false).
|
||||||
Build()
|
Build()
|
||||||
|
|
||||||
val := instance.New()
|
val := instance.New()
|
||||||
|
|
||||||
data := []byte(`
|
data := []byte(`
|
||||||
{
|
{
|
||||||
"int": 123,
|
"int": 123,
|
||||||
@ -37,9 +39,13 @@ func Test_dynamicStructImpl_New(t *testing.T) {
|
|||||||
"Boolean": true,
|
"Boolean": true,
|
||||||
"Slice": [1, 2, 3],
|
"Slice": [1, 2, 3],
|
||||||
"user": {"job":{"address":"beijing","company":{"name":"unknown"}}, "base":{"age": 1800, "name":"baicha"}},
|
"user": {"job":{"address":"beijing","company":{"name":"unknown"}}, "base":{"age": 1800, "name":"baicha"}},
|
||||||
"Anonymous": "avoid to read"
|
"Anonymous": "avoid to read",
|
||||||
|
"arr": [{"item":{"name":"item1","test":1}},{"item":{"name":"item2", "test":2}}],
|
||||||
|
"arr2": [[{"item":{"name":"item1","test":1}},{"item":{"name":"item2", "test":2}}]]
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
tType := reflect.TypeOf(val)
|
||||||
|
fmt.Println(tType, tType.Kind(), tType.Elem().Kind(), tType.Elem().Kind().String())
|
||||||
err := json.Unmarshal(data, &val)
|
err := json.Unmarshal(data, &val)
|
||||||
fmt.Println(err, val)
|
fmt.Println(err, val)
|
||||||
valByte, _ := json.Marshal(val)
|
valByte, _ := json.Marshal(val)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user