util/reflect: fix StructFields
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
07d4085201
commit
38d6e482d7
@ -7,6 +7,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrInvalidParam specifies invalid url query params
|
// ErrInvalidParam specifies invalid url query params
|
||||||
@ -233,10 +234,30 @@ func StructFields(src interface{}) ([]StructField, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch val.Interface().(type) {
|
||||||
|
case time.Time, *time.Time:
|
||||||
|
fields = append(fields, StructField{Field: fld, Value: val, Path: fld.Name})
|
||||||
|
continue
|
||||||
|
case time.Duration, *time.Duration:
|
||||||
|
fields = append(fields, StructField{Field: fld, Value: val, Path: fld.Name})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
switch val.Kind() {
|
switch val.Kind() {
|
||||||
// case timeKind:
|
case reflect.Ptr:
|
||||||
// fmt.Printf("GGG\n")
|
// if !val.IsValid()
|
||||||
// fields = append(fields, StructField{Field: fld, Value: val, Path: fld.Name})
|
if reflect.Indirect(val).Kind() == reflect.Struct {
|
||||||
|
infields, err := StructFields(val.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, infield := range infields {
|
||||||
|
infield.Path = fmt.Sprintf("%s.%s", fld.Name, infield.Path)
|
||||||
|
fields = append(fields, infield)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fields = append(fields, StructField{Field: fld, Value: val, Path: fld.Name})
|
||||||
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
infields, err := StructFields(val.Interface())
|
infields, err := StructFields(val.Interface())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,24 +4,45 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
rutil "go.unistack.org/micro/v3/util/reflect"
|
rutil "go.unistack.org/micro/v3/util/reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestStructfields(t *testing.T) {
|
||||||
|
type Config struct {
|
||||||
|
Wait time.Duration
|
||||||
|
Time time.Time
|
||||||
|
Metadata map[string]int
|
||||||
|
Broker string
|
||||||
|
Addr []string
|
||||||
|
Verbose bool
|
||||||
|
Nested *Config
|
||||||
|
}
|
||||||
|
cfg := &Config{Nested: &Config{}}
|
||||||
|
fields, err := rutil.StructFields(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(fields) != 13 {
|
||||||
|
t.Fatalf("invalid fields number: %v", fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetFieldByPath(t *testing.T) {
|
func TestSetFieldByPath(t *testing.T) {
|
||||||
type NestedStr struct {
|
type NestedStr struct {
|
||||||
BBB string `json:"bbb"`
|
BBB string `json:"bbb"`
|
||||||
CCC int `json:"ccc"`
|
CCC int `json:"ccc"`
|
||||||
}
|
}
|
||||||
type Str1 struct {
|
type Str1 struct {
|
||||||
Name []string `json:"name" codec:"flatten"`
|
Name []string `json:"name" codec:"flatten"`
|
||||||
XXX string `json:"xxx"`
|
XXX string `json:"xxx"`
|
||||||
Nested NestedStr `json:"nested"`
|
Nested NestedStr `json:"nested"`
|
||||||
}
|
}
|
||||||
type Str2 struct {
|
type Str2 struct {
|
||||||
XXX string `json:"xxx"`
|
XXX string `json:"xxx"`
|
||||||
Nested *NestedStr `json:"nested"`
|
Nested *NestedStr `json:"nested"`
|
||||||
Name []string `json:"name" codec:"flatten"`
|
Name []string `json:"name" codec:"flatten"`
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
val1 := &Str1{Name: []string{"first", "second"}, XXX: "ttt", Nested: NestedStr{BBB: "ddd", CCC: 9}}
|
val1 := &Str1{Name: []string{"first", "second"}, XXX: "ttt", Nested: NestedStr{BBB: "ddd", CCC: 9}}
|
||||||
@ -45,17 +66,17 @@ func TestSetFieldByPath(t *testing.T) {
|
|||||||
func TestZeroFieldByPath(t *testing.T) {
|
func TestZeroFieldByPath(t *testing.T) {
|
||||||
type NestedStr struct {
|
type NestedStr struct {
|
||||||
BBB string `json:"bbb"`
|
BBB string `json:"bbb"`
|
||||||
CCC int `json:"ccc"`
|
CCC int `json:"ccc"`
|
||||||
}
|
}
|
||||||
type Str1 struct {
|
type Str1 struct {
|
||||||
Name []string `json:"name" codec:"flatten"`
|
Name []string `json:"name" codec:"flatten"`
|
||||||
XXX string `json:"xxx"`
|
XXX string `json:"xxx"`
|
||||||
Nested NestedStr `json:"nested"`
|
Nested NestedStr `json:"nested"`
|
||||||
}
|
}
|
||||||
type Str2 struct {
|
type Str2 struct {
|
||||||
XXX string `json:"xxx"`
|
XXX string `json:"xxx"`
|
||||||
Nested *NestedStr `json:"nested"`
|
Nested *NestedStr `json:"nested"`
|
||||||
Name []string `json:"name" codec:"flatten"`
|
Name []string `json:"name" codec:"flatten"`
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
val1 := &Str1{Name: []string{"first", "second"}, XXX: "ttt", Nested: NestedStr{BBB: "ddd", CCC: 9}}
|
val1 := &Str1{Name: []string{"first", "second"}, XXX: "ttt", Nested: NestedStr{BBB: "ddd", CCC: 9}}
|
||||||
|
Loading…
Reference in New Issue
Block a user