mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 11:18:50 +08:00
fix issue in internal/structs.MapField
This commit is contained in:
parent
e06b62ecf2
commit
11e102e137
@ -12,21 +12,48 @@ package structs
|
||||
//
|
||||
// The parameter <priority> specifies the priority tag array for retrieving from high to low.
|
||||
//
|
||||
// The parameter <recursive> specifies whether retrieving the struct field recursively.
|
||||
//
|
||||
// Note that it only retrieves the exported attributes with first letter up-case from struct.
|
||||
func MapField(pointer interface{}, priority []string) (map[string]*Field, error) {
|
||||
tagFields, err := getFieldValuesByTagPriority(pointer, priority, map[string]struct{}{})
|
||||
fields, err := getFieldValues(pointer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tagFieldMap := make(map[string]*Field, len(tagFields))
|
||||
for _, field := range tagFields {
|
||||
tagField := field
|
||||
tagFieldMap[field.Name()] = tagField
|
||||
if tagField.TagValue != "" {
|
||||
tagFieldMap[tagField.TagValue] = tagField
|
||||
var (
|
||||
tagValue = ""
|
||||
mapField = make(map[string]*Field)
|
||||
)
|
||||
for _, field := range fields {
|
||||
// Only retrieve exported attributes.
|
||||
if !field.IsExported() {
|
||||
continue
|
||||
}
|
||||
tagValue = ""
|
||||
for _, p := range priority {
|
||||
tagValue = field.Tag(p)
|
||||
if tagValue != "" && tagValue != "-" {
|
||||
break
|
||||
}
|
||||
}
|
||||
tempField := field
|
||||
tempField.TagValue = tagValue
|
||||
if tagValue != "" {
|
||||
mapField[tagValue] = tempField
|
||||
} else {
|
||||
if field.IsEmbedded() {
|
||||
m, err := MapField(field.value, priority)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range m {
|
||||
if _, ok := mapField[k]; !ok {
|
||||
tempV := v
|
||||
mapField[k] = tempV
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mapField[field.Name()] = tempField
|
||||
}
|
||||
}
|
||||
}
|
||||
return tagFieldMap, nil
|
||||
return mapField, nil
|
||||
}
|
||||
|
@ -101,3 +101,26 @@ func Test_StructOfNilPointer(t *testing.T) {
|
||||
t.Assert(m, g.Map{"name": "Name", "pass2": "Pass"})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_MapField(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Name string `params:"name"`
|
||||
Pass string `my-tag1:"pass1" my-tag2:"pass2" params:"pass"`
|
||||
}
|
||||
var user *User
|
||||
m, _ := structs.MapField(user, []string{"params"})
|
||||
t.Assert(len(m), 3)
|
||||
_, ok := m["Id"]
|
||||
t.Assert(ok, true)
|
||||
_, ok = m["Name"]
|
||||
t.Assert(ok, false)
|
||||
_, ok = m["name"]
|
||||
t.Assert(ok, true)
|
||||
_, ok = m["Pass"]
|
||||
t.Assert(ok, false)
|
||||
_, ok = m["pass"]
|
||||
t.Assert(ok, true)
|
||||
})
|
||||
}
|
||||
|
@ -556,33 +556,33 @@ func Test_Params_Modify(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
//func Test_Params_Parse_DefaultValueTag(t *testing.T) {
|
||||
// type T struct {
|
||||
// Name string `d:"john"`
|
||||
// Score float32 `d:"60"`
|
||||
// }
|
||||
// p, _ := ports.PopRand()
|
||||
// s := g.Server(p)
|
||||
// s.BindHandler("/parse", func(r *ghttp.Request) {
|
||||
// var t *T
|
||||
// if err := r.Parse(&t); err != nil {
|
||||
// r.Response.WriteExit(err)
|
||||
// }
|
||||
// r.Response.WriteExit(t)
|
||||
// })
|
||||
// s.SetPort(p)
|
||||
// s.SetDumpRouterMap(false)
|
||||
// s.Start()
|
||||
// defer s.Shutdown()
|
||||
//
|
||||
// time.Sleep(100 * time.Millisecond)
|
||||
// gtest.C(t, func(t *gtest.T) {
|
||||
// prefix := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||
// client := g.Client()
|
||||
// client.SetPrefix(prefix)
|
||||
//
|
||||
// t.Assert(client.PostContent("/parse"), `{"Name":"john","Score":60}`)
|
||||
// t.Assert(client.PostContent("/parse", `{"name":"smith"}`), `{"Name":"smith","Score":60}`)
|
||||
// t.Assert(client.PostContent("/parse", `{"name":"smith", "score":100}`), `{"Name":"smith","Score":100}`)
|
||||
// })
|
||||
//}
|
||||
func Test_Params_Parse_DefaultValueTag(t *testing.T) {
|
||||
type T struct {
|
||||
Name string `d:"john"`
|
||||
Score float32 `d:"60"`
|
||||
}
|
||||
p, _ := ports.PopRand()
|
||||
s := g.Server(p)
|
||||
s.BindHandler("/parse", func(r *ghttp.Request) {
|
||||
var t *T
|
||||
if err := r.Parse(&t); err != nil {
|
||||
r.Response.WriteExit(err)
|
||||
}
|
||||
r.Response.WriteExit(t)
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
prefix := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||
client := g.Client()
|
||||
client.SetPrefix(prefix)
|
||||
|
||||
t.Assert(client.PostContent("/parse"), `{"Name":"john","Score":60}`)
|
||||
t.Assert(client.PostContent("/parse", `{"name":"smith"}`), `{"Name":"smith","Score":60}`)
|
||||
t.Assert(client.PostContent("/parse", `{"name":"smith", "score":100}`), `{"Name":"smith","Score":100}`)
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user