77 "reflect"
88 "strconv"
99 "strings"
10+ "time"
1011)
1112
1213const (
@@ -16,6 +17,11 @@ const (
1617 valueDiveLen = len (valueDive )
1718)
1819
20+ var (
21+ timeDurationType = reflect .TypeOf (time .Duration (0 ))
22+ timeType = reflect .TypeOf (time.Time {})
23+ )
24+
1925type structInitSelector func (v reflect.Value , visitedStruct map [reflect.Type ]bool ) error
2026
2127func checkPtr (i interface {}) (reflect.Value , error ) {
@@ -32,6 +38,7 @@ func Init(i interface{}) error {
3238 if err != nil {
3339 return err
3440 }
41+ defer callInit (v )
3542 return initStruct (v .Elem (), maybeInit , make (map [reflect.Type ]bool ))
3643}
3744
@@ -46,11 +53,11 @@ func JustInit(i interface{}) error {
4653 if err != nil {
4754 return err
4855 }
56+ defer callInit (v )
4957 return initStruct (v .Elem (), justInit , make (map [reflect.Type ]bool ))
5058}
5159
5260func initStruct (v reflect.Value , selector structInitSelector , visitedStruct map [reflect.Type ]bool ) error {
53- defer callInit (v )
5461 if ! v .CanSet () {
5562 return nil
5663 }
@@ -69,7 +76,7 @@ func justInit(v reflect.Value, visitedStruct map[reflect.Type]bool) error {
6976 fieldErrors := make ([]* ErrorJustInitField , 0 )
7077 t := v .Type ()
7178 for i := 0 ; i < t .NumField (); i ++ {
72- if val , ok := t .Field (i ).Tag .Lookup (tagNameDefault ); val != "-" && ok {
79+ if val := t .Field (i ).Tag .Get (tagNameDefault ); val != "-" {
7380 if err := initField (v , v .Field (i ), val , justInit , visitedStruct ); err != nil {
7481 ft := t .Field (i )
7582 typeName := ft .Type .Name ()
@@ -98,7 +105,7 @@ func justInit(v reflect.Value, visitedStruct map[reflect.Type]bool) error {
98105func maybeInit (v reflect.Value , visitedStruct map [reflect.Type ]bool ) error {
99106 t := v .Type ()
100107 for i := 0 ; i < t .NumField (); i ++ {
101- if val , ok := t .Field (i ).Tag .Lookup (tagNameDefault ); val != "-" && ok {
108+ if val := t .Field (i ).Tag .Get (tagNameDefault ); val != "-" {
102109 if err := initField (v , v .Field (i ), val , maybeInit , visitedStruct ); err != nil {
103110 return err
104111 }
@@ -114,17 +121,68 @@ func initField(structVal reflect.Value, fieldVal reflect.Value, defVal string, s
114121 return nil
115122 }
116123
117- switch k := fieldVal .Kind (); k {
118- case reflect .Invalid :
119- return nil
124+ fieldType := fieldVal .Type ()
125+
126+ //special type
127+ switch fieldType {
128+ case timeDurationType :
129+ if d , err := time .ParseDuration (defVal ); err != nil {
130+ return err
131+ } else {
132+ fieldVal .Set (reflect .ValueOf (d ))
133+ return nil
134+ }
135+ case timeType :
136+ if defVal == "now" {
137+ fieldVal .Set (reflect .ValueOf (time .Now ()))
138+ return nil
139+ } else if strings .HasPrefix (defVal , "+" ) || strings .HasPrefix (defVal , "-" ) {
140+ d , err := time .ParseDuration (defVal )
141+ if err != nil {
142+ return err
143+ }
144+
145+ fieldVal .Set (reflect .ValueOf (time .Now ().Add (d )))
146+ return nil
147+ }
148+ }
149+
150+ k := fieldVal .Kind ()
151+
152+ // maybe Init function callable type
153+ switch k {
120154 case reflect .Ptr :
121155 elem := fieldVal .Elem ()
122156 if elem .Kind () == reflect .Invalid {
123- fieldVal .Set (reflect .New (fieldVal . Type () .Elem ()))
157+ fieldVal .Set (reflect .New (fieldType .Elem ()))
124158 elem = fieldVal .Elem ()
125159 }
126- defer callInit (fieldVal )
160+ if elem .Kind () != reflect .Struct {
161+ defer callInit (fieldVal )
162+ }
127163 return initField (structVal , elem , defVal , selector , visitedStruct )
164+ case reflect .Struct :
165+ if fieldVal .CanAddr () {
166+ defer callInit (fieldVal )
167+ }
168+
169+ if defVal == valueDive {
170+ return initStruct (fieldVal , selector , visitedStruct )
171+ } else if defVal != "" {
172+ if err := jsonUnmarshalValue (fieldVal , defVal ); err != nil {
173+ return err
174+ }
175+ }
176+ }
177+
178+ if defVal == "" {
179+ return nil
180+ }
181+
182+ // primitive type
183+ switch k {
184+ case reflect .Invalid :
185+ return nil
128186 case reflect .String :
129187 fieldVal .SetString (defVal )
130188 case reflect .Bool :
@@ -165,16 +223,16 @@ func initField(structVal reflect.Value, fieldVal reflect.Value, defVal string, s
165223 }
166224 case reflect .Interface :
167225 if defVal == "" {
168- fieldVal .Set (reflect .Zero (fieldVal . Type () ))
226+ fieldVal .Set (reflect .Zero (fieldType ))
169227 } else if err := jsonUnmarshalValue (fieldVal , defVal ); err != nil {
170228 return err
171229 }
172230 case reflect .Map :
173231 if strings .HasPrefix (defVal , valueDive + "{" ) && strings .HasSuffix (defVal , "}" ) {
174- keyType := fieldVal . Type () .Key ()
175- valType := fieldVal . Type () .Elem ()
232+ keyType := fieldType .Key ()
233+ valType := fieldType .Elem ()
176234
177- fieldVal .Set (reflect .MakeMap (fieldVal . Type () ))
235+ fieldVal .Set (reflect .MakeMap (fieldType ))
178236
179237 tmp := defVal [valueDiveLen + 1 :len (defVal )- 1 ]
180238 flag := byte (0x00 )
@@ -237,12 +295,6 @@ func initField(structVal reflect.Value, fieldVal reflect.Value, defVal string, s
237295 } else if err := jsonUnmarshalValue (fieldVal , defVal ); err != nil {
238296 return err
239297 }
240- case reflect .Struct :
241- if defVal == valueDive {
242- return initStruct (fieldVal , selector , visitedStruct )
243- } else if err := jsonUnmarshalValue (fieldVal , defVal ); err != nil {
244- return err
245- }
246298 case reflect .Slice :
247299 if strings .HasPrefix (defVal , valueDive + "(" ) {
248300 tmp := defVal [valueDiveLen + 1 :]
@@ -295,7 +347,7 @@ func initField(structVal reflect.Value, fieldVal reflect.Value, defVal string, s
295347 }
296348 val = val [1 :]
297349
298- fieldVal .Set (reflect .MakeSlice (fieldVal . Type () , ln , cp ))
350+ fieldVal .Set (reflect .MakeSlice (fieldType , ln , cp ))
299351 for i := 0 ; i < ln ; i ++ {
300352 if err := initField (structVal , fieldVal .Index (i ), val , selector , visitedStruct ); err != nil {
301353 return err
@@ -326,7 +378,7 @@ func initField(structVal reflect.Value, fieldVal reflect.Value, defVal string, s
326378 } else if i , err := strconv .Atoi (defVal ); err != nil {
327379 return err
328380 } else {
329- fieldVal .Set (reflect .MakeChan (fieldVal . Type () , i ))
381+ fieldVal .Set (reflect .MakeChan (fieldType , i ))
330382 }
331383 case reflect .Func :
332384 srcFunc , ok := funcMap [defVal ]
@@ -346,7 +398,7 @@ func initField(structVal reflect.Value, fieldVal reflect.Value, defVal string, s
346398 if srcType .Kind () != reflect .Func {
347399 return errors .New ("return value must be function type" )
348400 }
349- vType := fieldVal . Type ()
401+ vType := fieldType
350402 if vType .NumIn () != srcType .NumIn () {
351403 return errors .New ("args count not equal" )
352404 } else if vType .NumOut () != srcType .NumOut () {
0 commit comments