-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconfig_source.go
83 lines (70 loc) · 2.62 KB
/
config_source.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
package alligotor
import (
"reflect"
)
// Field is a struct to hold all information for a struct's field that should be filled with configuration.
type Field struct {
// base contains all the parents properties' names in order.
base []Field
// name is the name of the current property.
name string
// description contains the value contained in the description struct tag.
description string
// value contains the reflect.Value of the field to set it's value.
value reflect.Value
// configs contains structtag key -> value string and can be read to interpret the field's struct tags for
// custom behavior like overrides.
configs map[string]string
}
func NewField(base []Field, name, description string, value reflect.Value, configs map[string]string) Field {
return Field{
base: base,
name: name,
description: description,
value: value,
configs: configs,
}
}
func (f *Field) Base() []Field {
return f.base
}
func (f *Field) BaseNames(nameExtractFunc func(*Field) string) []string {
baseNames := make([]string, 0, len(f.Base()))
for _, field := range f.Base() {
localField := field
name := nameExtractFunc(&localField)
baseNames = append(baseNames, name)
}
return baseNames
}
func (f *Field) Name() string {
return f.name
}
func (f *Field) Description() string {
return f.description
}
func (f *Field) Configs() map[string]string {
return f.configs
}
// Type returns the type of the package. This can be used to switch on the type to parse for example a string
// to the right target type.
func (f *Field) Type() reflect.Type {
return f.value.Type()
}
// ConfigSource consists of one method that gets a certain field and should return its value.
// If this value is a string and should be parsed (for example env variables can only be retrieved as a string but
// could also resemble an int value or even a string slice), a []byte should be returned.
//
// If anything else than a byte slice is returned the given value will be used as is and if there's a type mismatch
// an error will be reported.
type ConfigSource interface {
Read(field *Field) (interface{}, error)
}
// ConfigSourceInitializer is an optional interface to implement and can be used to initialize the config source
// before reading the fields one by one with the Read method of ConfigSource.
type ConfigSourceInitializer interface {
// Init should be called right before Read to initialize stuff.
// Some things shouldn't be initialized in the constructor since the environment or files (the config source)
// could be altered in the time between constructing a config source and calling the Read method.
Init(fields []Field) error
}