-
Notifications
You must be signed in to change notification settings - Fork 0
/
params.go
85 lines (70 loc) · 2.01 KB
/
params.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
package klash
import (
"errors"
"fmt"
"reflect"
)
type Params struct {
Mapping map[string]*Parameter
Listing []*Parameter
}
// Params store the mapping of ParamName -> Parameter for the given structure.
// Since multiple names can be affected to a single parameter, multiple
// keys can be associated with a single parameter.
func MakeParams(fieldCount int) *Params {
return &Params{
make(map[string]*Parameter),
make([]*Parameter, 0, fieldCount),
}
}
func NewParams(parameters interface{}) (*Params, error) {
pvalue := reflect.ValueOf(parameters)
if pvalue.Kind() != reflect.Ptr || pvalue.Elem().Kind() != reflect.Struct {
return nil, errors.New("klash: Pointer to struct expected")
}
fieldCount := pvalue.Type().Elem().NumField()
params := MakeParams(fieldCount)
if err := params.Parse(&pvalue); err != nil {
return nil, err
}
return params, nil
}
// Parse discovers the given parameters structure and associates the structure's
// field names with their values into the Params structure.
func (p *Params) Parse(pvalue *reflect.Value) error {
vtype := pvalue.Type().Elem()
for idx := 0; idx < vtype.NumField(); idx++ {
field := vtype.Field(idx)
value := pvalue.Elem().Field(idx)
if value.Kind() == reflect.Slice {
value.Set(reflect.MakeSlice(value.Type(), 0, 0))
}
parameter := NewParameter(field.Name, value)
if err := parameter.DiscoverProperties(field.Tag); err != nil {
return err
}
if err := p.Set(parameter.Name, parameter); err != nil {
return err
}
if parameter.Alias != "" {
if err := p.Set(parameter.Alias, parameter); err != nil {
return err
}
}
p.Listing = append(p.Listing, parameter)
}
return nil
}
func (p *Params) Get(key string) (*Parameter, bool) {
val, ok := p.Mapping[DecomposeName(key, true)]
return val, ok
}
func (p *Params) Set(key string, value *Parameter) error {
key = DecomposeName(key, true)
_, ok := p.Mapping[key]
if ok {
return fmt.Errorf("klash: %s is already an argument or an alias", key)
}
p.Mapping[key] = value
return nil
}