Skip to content

Commit 508ece0

Browse files
committed
improved filler
1 parent c889686 commit 508ece0

File tree

2 files changed

+132
-13
lines changed

2 files changed

+132
-13
lines changed

filler.go

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ type fieldData struct {
1212

1313
type fillerFunc func(field *fieldData, config string)
1414

15+
// Filler contains all the functions to fill any struct field with any type
16+
// allowing to define function by Kind, Type of field name
1517
type Filler struct {
18+
FuncByName map[string]fillerFunc
1619
FuncByType map[TypeHash]fillerFunc
1720
FuncByKind map[reflect.Kind]fillerFunc
1821
Tag string
1922
}
2023

24+
// Fill apply all the functions contained on Filler, setting all the possible
25+
// values
2126
func (f *Filler) Fill(variable interface{}) {
2227
fields := f.getFields(variable)
2328
f.setDefaultValues(fields)
@@ -33,7 +38,7 @@ func (f *Filler) getFieldsFromValue(valueObject reflect.Value) []*fieldData {
3338
typeObject := valueObject.Type()
3439

3540
count := valueObject.NumField()
36-
results := make([]*fieldData, 0)
41+
var results []*fieldData
3742
for i := 0; i < count; i++ {
3843
value := valueObject.Field(i)
3944
field := typeObject.Field(i)
@@ -91,39 +96,52 @@ func (f *Filler) isEmpty(field *fieldData) bool {
9196
func (f *Filler) setDefaultValue(field *fieldData) {
9297
tagValue := field.Field.Tag.Get(f.Tag)
9398

94-
function := f.getFunctionByType(field.Field.Type)
95-
if function != nil {
96-
function(field, tagValue)
97-
return
99+
getters := []func(field *fieldData) fillerFunc{
100+
f.getFunctionByName,
101+
f.getFunctionByType,
102+
f.getFunctionByKind,
98103
}
99104

100-
function = f.getFunctionByKind(field.Field.Type.Kind())
101-
if function != nil {
102-
function(field, tagValue)
103-
return
105+
for _, getter := range getters {
106+
filler := getter(field)
107+
if filler != nil {
108+
filler(field, tagValue)
109+
return
110+
}
104111
}
105112

106113
return
107114
}
108115

109-
func (f *Filler) getFunctionByType(t reflect.Type) fillerFunc {
110-
if f, ok := f.FuncByType[GetTypeHash(t)]; ok == true {
116+
func (f *Filler) getFunctionByName(field *fieldData) fillerFunc {
117+
if f, ok := f.FuncByName[field.Field.Name]; ok == true {
118+
return f
119+
}
120+
121+
return nil
122+
}
123+
124+
func (f *Filler) getFunctionByType(field *fieldData) fillerFunc {
125+
if f, ok := f.FuncByType[GetTypeHash(field.Field.Type)]; ok == true {
111126
return f
112127
}
113128

114129
return nil
115130
}
116131

117-
func (f *Filler) getFunctionByKind(k reflect.Kind) fillerFunc {
118-
if f, ok := f.FuncByKind[k]; ok == true {
132+
func (f *Filler) getFunctionByKind(field *fieldData) fillerFunc {
133+
if f, ok := f.FuncByKind[field.Field.Type.Kind()]; ok == true {
119134
return f
120135
}
121136

122137
return nil
123138
}
124139

140+
// TypeHash is a string representing a reflect.Type following the next pattern:
141+
// <package.name>.<type.name>
125142
type TypeHash string
126143

144+
// GetTypeHash returns the TypeHash for a given reflect.Type
127145
func GetTypeHash(t reflect.Type) TypeHash {
128146
if t.Kind() == reflect.Ptr {
129147
t = t.Elem()

filler_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package defaults
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
7+
. "gopkg.in/check.v1"
8+
)
9+
10+
type FillerSuite struct{}
11+
12+
var _ = Suite(&FillerSuite{})
13+
14+
type FixtureTypeInt int
15+
16+
func (s *FillerSuite) TestFuncByNameIsEmpty(c *C) {
17+
calledA := false
18+
calledB := false
19+
20+
f := &Filler{
21+
FuncByName: map[string]fillerFunc{
22+
"Foo": func(field *fieldData, tagValue string) {
23+
calledA = true
24+
},
25+
},
26+
FuncByKind: map[reflect.Kind]fillerFunc{
27+
reflect.Int: func(field *fieldData, tagValue string) {
28+
calledB = true
29+
},
30+
},
31+
}
32+
33+
f.Fill(&struct{ Foo int }{})
34+
c.Assert(calledA, Equals, true)
35+
c.Assert(calledB, Equals, false)
36+
}
37+
38+
func (s *FillerSuite) TestFuncByTypeIsEmpty(c *C) {
39+
calledA := false
40+
calledB := false
41+
42+
t := GetTypeHash(reflect.TypeOf(new(FixtureTypeInt)))
43+
f := &Filler{
44+
FuncByType: map[TypeHash]fillerFunc{
45+
t: func(field *fieldData, tagValue string) {
46+
calledA = true
47+
},
48+
},
49+
FuncByKind: map[reflect.Kind]fillerFunc{
50+
reflect.Int: func(field *fieldData, tagValue string) {
51+
calledB = true
52+
},
53+
},
54+
}
55+
56+
f.Fill(&struct{ Foo FixtureTypeInt }{})
57+
c.Assert(calledA, Equals, true)
58+
c.Assert(calledB, Equals, false)
59+
}
60+
61+
func (s *FillerSuite) TestFuncByKindIsNotEmpty(c *C) {
62+
called := false
63+
f := &Filler{FuncByKind: map[reflect.Kind]fillerFunc{
64+
reflect.Int: func(field *fieldData, tagValue string) {
65+
called = true
66+
},
67+
}}
68+
69+
f.Fill(&struct{ Foo int }{Foo: 42})
70+
c.Assert(called, Equals, false)
71+
}
72+
73+
func (s *FillerSuite) TestFuncByKindSlice(c *C) {
74+
fmt.Println(GetTypeHash(reflect.TypeOf(new([]string))))
75+
}
76+
77+
func (s *FillerSuite) TestFuncByKindTag(c *C) {
78+
var called string
79+
f := &Filler{Tag: "foo", FuncByKind: map[reflect.Kind]fillerFunc{
80+
reflect.Int: func(field *fieldData, tagValue string) {
81+
called = tagValue
82+
},
83+
}}
84+
85+
f.Fill(&struct {
86+
Foo int `foo:"qux"`
87+
}{})
88+
c.Assert(called, Equals, "qux")
89+
}
90+
91+
func (s *FillerSuite) TestFuncByKindIsEmpty(c *C) {
92+
called := false
93+
f := &Filler{FuncByKind: map[reflect.Kind]fillerFunc{
94+
reflect.Int: func(field *fieldData, tagValue string) {
95+
called = true
96+
},
97+
}}
98+
99+
f.Fill(&struct{ Foo int }{})
100+
c.Assert(called, Equals, true)
101+
}

0 commit comments

Comments
 (0)