-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.go
115 lines (104 loc) · 2.63 KB
/
parser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package envconf
import (
"flag"
"github.com/antonmashko/envconf/external"
"github.com/antonmashko/envconf/option"
)
type EnvConf struct {
opts *option.Options
}
func New() *EnvConf {
return &EnvConf{
opts: &option.Options{},
}
}
func (e *EnvConf) fieldInitialized(f field) {
cf := asConfigField(f)
if cf == nil {
return
}
dv, _ := cf.configuration.defaultValue.Value()
e.opts.OnFieldInitialized(option.FieldInitializedArg{
Name: cf.name(),
FullName: cf.fullName(),
Type: cf.StructField.Type,
Required: cf.property.required,
Description: cf.property.description,
FlagName: cf.configuration.flag.Name(),
EnvName: cf.configuration.env.Name(),
DefaultValue: dv,
})
}
func (e *EnvConf) fieldDefined(f field) {
cf := asConfigField(f)
if cf == nil || !cf.isSet() {
return
}
dv, _ := cf.configuration.defaultValue.Value()
e.opts.OnFieldDefined(option.FieldDefinedArg{
Name: cf.name(),
FullName: cf.fullName(),
Type: cf.StructField.Type,
Required: cf.property.required,
Description: cf.property.description,
FlagName: cf.configuration.flag.Name(),
EnvName: cf.configuration.env.Name(),
DefaultValue: dv,
Value: cf.value,
Source: cf.source,
})
}
func (e *EnvConf) fieldNotDefined(f field, err error) {
cf := asConfigField(f)
if cf == nil {
return
}
e.opts.OnFieldDefineErr(option.FieldDefineErrorArg{
Name: cf.name(),
FullName: cf.fullName(),
Err: err,
})
}
// Parse define variables inside data from different sources,
// such as flag/environment variable or default value
func (e *EnvConf) Parse(data interface{}, opts ...option.ClientOption) error {
if data == nil {
return ErrNilData
}
// enable help output
option.WithCustomUsage().Apply(e.opts)
for i := range opts {
opts[i].Apply(e.opts)
}
extMapper := external.NewExternalConfigMapper(e.opts.External())
p, err := newParentStructType(data, e)
if err != nil {
return err
}
if err = p.init(); err != nil {
return err
}
if e.opts.Usage() != nil {
flag.Usage = e.opts.Usage()
}
flag.Parse()
if fp := e.opts.FlagParsed(); fp != nil {
if err = fp(); err != nil {
return err
}
}
if err = extMapper.Unmarshal(data); err != nil {
return err
}
p.ext = extMapper.Data()
return p.define()
}
// PriorityOrder return parsing priority order
func (e *EnvConf) PriorityOrder() []option.ConfigSource {
return e.opts.PriorityOrder()
}
// Parse define variables inside data from different sources,
// such as flag/environment variable or default value
func Parse(data interface{}, opts ...option.ClientOption) error {
return New().Parse(data, opts...)
}