@@ -115,7 +115,6 @@ func processFile(config interface{}, file string, errorOnUnmatchedKeys bool) err
115
115
case strings .HasSuffix (file , ".json" ):
116
116
return unmarshalJSON (data , config , errorOnUnmatchedKeys )
117
117
default :
118
-
119
118
if err := unmarshalToml (data , config , errorOnUnmatchedKeys ); err == nil {
120
119
return nil
121
120
} else if errUnmatchedKeys , ok := err .(* UnmatchedTomlKeysError ); ok {
@@ -188,6 +187,55 @@ func getPrefixForStruct(prefixes []string, fieldStruct *reflect.StructField) []s
188
187
return append (prefixes , fieldStruct .Name )
189
188
}
190
189
190
+ func (configor * Configor ) processDefaults (config interface {}) error {
191
+ configValue := reflect .Indirect (reflect .ValueOf (config ))
192
+ if configValue .Kind () != reflect .Struct {
193
+ return errors .New ("invalid config, should be struct" )
194
+ }
195
+
196
+ configType := configValue .Type ()
197
+ for i := 0 ; i < configType .NumField (); i ++ {
198
+ var (
199
+ fieldStruct = configType .Field (i )
200
+ field = configValue .Field (i )
201
+ )
202
+
203
+ if ! field .CanAddr () || ! field .CanInterface () {
204
+ continue
205
+ }
206
+
207
+ if isBlank := reflect .DeepEqual (field .Interface (), reflect .Zero (field .Type ()).Interface ()); isBlank {
208
+ // Set default configuration if blank
209
+ if value := fieldStruct .Tag .Get ("default" ); value != "" {
210
+ if err := yaml .Unmarshal ([]byte (value ), field .Addr ().Interface ()); err != nil {
211
+ return err
212
+ }
213
+ }
214
+ }
215
+
216
+ for field .Kind () == reflect .Ptr {
217
+ field = field .Elem ()
218
+ }
219
+
220
+ switch field .Kind () {
221
+ case reflect .Struct :
222
+ if err := configor .processDefaults (field .Addr ().Interface ()); err != nil {
223
+ return err
224
+ }
225
+ case reflect .Slice :
226
+ for i := 0 ; i < field .Len (); i ++ {
227
+ if reflect .Indirect (field .Index (i )).Kind () == reflect .Struct {
228
+ if err := configor .processDefaults (field .Index (i ).Addr ().Interface ()); err != nil {
229
+ return err
230
+ }
231
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ return nil
237
+ }
238
+
191
239
func (configor * Configor ) processTags (config interface {}, prefixes ... string ) error {
192
240
configValue := reflect .Indirect (reflect .ValueOf (config ))
193
241
if configValue .Kind () != reflect .Struct {
@@ -244,16 +292,9 @@ func (configor *Configor) processTags(config interface{}, prefixes ...string) er
244
292
}
245
293
}
246
294
247
- if isBlank := reflect .DeepEqual (field .Interface (), reflect .Zero (field .Type ()).Interface ()); isBlank {
248
- // Set default configuration if blank
249
- if value := fieldStruct .Tag .Get ("default" ); value != "" {
250
- if err := yaml .Unmarshal ([]byte (value ), field .Addr ().Interface ()); err != nil {
251
- return err
252
- }
253
- } else if fieldStruct .Tag .Get ("required" ) == "true" {
254
- // return error if it is required but blank
255
- return errors .New (fieldStruct .Name + " is required, but blank" )
256
- }
295
+ if isBlank := reflect .DeepEqual (field .Interface (), reflect .Zero (field .Type ()).Interface ()); isBlank && fieldStruct .Tag .Get ("required" ) == "true" {
296
+ // return error if it is required but blank
297
+ return errors .New (fieldStruct .Name + " is required, but blank" )
257
298
}
258
299
259
300
for field .Kind () == reflect .Ptr {
@@ -267,8 +308,7 @@ func (configor *Configor) processTags(config interface{}, prefixes ...string) er
267
308
}
268
309
269
310
if field .Kind () == reflect .Slice {
270
- arrLen := field .Len ()
271
- if arrLen > 0 {
311
+ if arrLen := field .Len (); arrLen > 0 {
272
312
for i := 0 ; i < arrLen ; i ++ {
273
313
if reflect .Indirect (field .Index (i )).Kind () == reflect .Struct {
274
314
if err := configor .processTags (field .Index (i ).Addr ().Interface (), append (getPrefixForStruct (prefixes , & fieldStruct ), fmt .Sprint (i ))... ); err != nil {
@@ -327,6 +367,9 @@ func (configor *Configor) load(config interface{}, watchMode bool, files ...stri
327
367
}
328
368
}
329
369
370
+ // process defaults
371
+ configor .processDefaults (config )
372
+
330
373
for _ , file := range configFiles {
331
374
if configor .Config .Debug || configor .Config .Verbose {
332
375
fmt .Printf ("Loading configurations from file '%v'...\n " , file )
0 commit comments