Skip to content

Commit ff0ba6e

Browse files
yang.yumcuadros
authored andcommitted
add nested slice support (cherry-pick)
1 parent fb68a23 commit ff0ba6e

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

defaults.go

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package defaults
22

33
import (
44
"reflect"
5+
"regexp"
56
"strconv"
7+
"strings"
68
"time"
79
)
810

@@ -79,6 +81,17 @@ func newDefaultFiller() *Filler {
7981
field.Value.SetString(field.TagValue)
8082
}
8183

84+
funcs[reflect.Struct] = func(field *FieldData) {
85+
fields := getDefaultFiller().GetFieldsFromValue(field.Value, nil)
86+
getDefaultFiller().SetDefaultValues(fields)
87+
}
88+
89+
types := make(map[TypeHash]FillerFunc, 1)
90+
types["time.Duration"] = func(field *FieldData) {
91+
d, _ := time.ParseDuration(field.TagValue)
92+
field.Value.Set(reflect.ValueOf(d))
93+
}
94+
8295
funcs[reflect.Slice] = func(field *FieldData) {
8396
k := field.Value.Type().Elem().Kind()
8497
switch k {
@@ -93,19 +106,32 @@ func newDefaultFiller() *Filler {
93106
fields := getDefaultFiller().GetFieldsFromValue(field.Value.Index(i), nil)
94107
getDefaultFiller().SetDefaultValues(fields)
95108
}
109+
default:
110+
//处理形如 [1,2,3,4]
111+
reg := regexp.MustCompile(`^\[(.*)\]$`)
112+
matchs := reg.FindStringSubmatch(field.TagValue)
113+
if len(matchs) != 2 {
114+
return
115+
}
116+
if matchs[1] == "" {
117+
field.Value.Set(reflect.MakeSlice(field.Value.Type(), 0, 0))
118+
} else {
119+
defaultValue := strings.Split(matchs[1], ",")
120+
result := reflect.MakeSlice(field.Value.Type(), len(defaultValue), len(defaultValue))
121+
for i := 0; i < len(defaultValue); i++ {
122+
itemValue := result.Index(i)
123+
item := &FieldData{
124+
Value: itemValue,
125+
Field: reflect.StructField{},
126+
TagValue: defaultValue[i],
127+
Parent: nil,
128+
}
129+
funcs[k](item)
130+
}
131+
field.Value.Set(result)
132+
}
96133
}
97134
}
98135

99-
funcs[reflect.Struct] = func(field *FieldData) {
100-
fields := getDefaultFiller().GetFieldsFromValue(field.Value, nil)
101-
getDefaultFiller().SetDefaultValues(fields)
102-
}
103-
104-
types := make(map[TypeHash]FillerFunc, 1)
105-
types["time.Duration"] = func(field *FieldData) {
106-
d, _ := time.ParseDuration(field.TagValue)
107-
field.Value.Set(reflect.ValueOf(d))
108-
}
109-
110136
return &Filler{FuncByKind: funcs, FuncByType: types, Tag: "default"}
111137
}

defaults_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ type ExampleBasic struct {
4343
Bool bool `default:"true"`
4444
Integer int `default:"33"`
4545
}
46-
Duration time.Duration `default:"1s"`
47-
Children []Child
48-
Second time.Duration `default:"1s"`
46+
Duration time.Duration `default:"1s"`
47+
Children []Child
48+
Second time.Duration `default:"1s"`
49+
StringSlice []string `default:"[1,2,3,4]"`
50+
IntSlice []int `default:"[1,2,3,4]"`
51+
IntSliceSlice [][]int `default:"[[1],[2],[3],[4]]"`
52+
StringSliceSlice [][]string `default:"[[1],[]]"`
4953
}
5054

5155
func (s *DefaultsSuite) TestSetDefaultsBasic(c *C) {
@@ -86,6 +90,10 @@ func (s *DefaultsSuite) assertTypes(c *C, foo *ExampleBasic) {
8690
c.Assert(foo.Duration, Equals, time.Second)
8791
c.Assert(foo.Children, IsNil)
8892
c.Assert(foo.Second, Equals, time.Second)
93+
c.Assert(foo.StringSlice, DeepEquals, []string{"1", "2", "3", "4"})
94+
c.Assert(foo.IntSlice, DeepEquals, []int{1, 2, 3, 4})
95+
c.Assert(foo.IntSliceSlice, DeepEquals, [][]int{[]int{1}, []int{2}, []int{3}, []int{4}})
96+
c.Assert(foo.StringSliceSlice, DeepEquals, [][]string{[]string{"1"}, []string{}})
8997
}
9098

9199
func (s *DefaultsSuite) TestSetDefaultsWithValues(c *C) {

0 commit comments

Comments
 (0)