-
Notifications
You must be signed in to change notification settings - Fork 212
/
parameters.go
112 lines (94 loc) · 2.46 KB
/
parameters.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
package parameters
import (
"fmt"
"strconv"
"time"
)
// New creates Parameters instance with default values.
func New() *Parameters {
return &Parameters{values: map[string]string{}}
}
// FromValues instantiates parameters with a cope of values.
func FromValues(values map[string]string) *Parameters {
p := New()
p.Update(values)
return p
}
type Parameters struct {
values map[string]string
}
func (p *Parameters) Update(values map[string]string) {
for name, value := range values {
p.values[name] = value
}
}
type Parser[T any] func(string) (T, error)
type Parameter[T any] struct {
name, desc string
defaults T
parser Parser[T]
}
func (p *Parameter[T]) Get(params *Parameters) T {
value, exist := params.values[p.name]
var rst T
if !exist {
return p.defaults
}
rst, err := p.parser(value)
if err != nil {
// TODO(dshulyak) move this to part to validation that is executed
// when values are updated (Parameters.Update)
panic(fmt.Sprintf("invalid parameter %s: %s. default (%v): %v", p.name, p.desc, p.defaults, err))
}
return rst
}
func NewParameter[T any](name, desc string, defaults T, parser Parser[T]) Parameter[T] {
return Parameter[T]{name: name, desc: desc, defaults: defaults, parser: parser}
}
func String(name, desc, defaults string) Parameter[string] {
return NewParameter(name, desc, defaults, toString)
}
func Bytes(name, desc string, defaults []byte) Parameter[[]byte] {
return NewParameter(name, desc, defaults, toBytes)
}
func Duration(name, desc string, defaults time.Duration) Parameter[time.Duration] {
return NewParameter(name, desc, defaults, toDuration)
}
func Int(name, desc string, defaults int) Parameter[int] {
return NewParameter(name, desc, defaults, toInt)
}
func Bool(name, desc string) Parameter[bool] {
return NewParameter(name, desc, false, func(value string) (bool, error) {
switch value {
case "true":
return true, nil
case "1":
return true, nil
case "false":
return false, nil
case "0":
return false, nil
}
return false, fmt.Errorf("not a boolean %v", value)
})
}
func toBytes(value string) ([]byte, error) {
return []byte(value), nil
}
func toString(value string) (string, error) {
return value, nil
}
func toInt(value string) (int, error) {
rst, err := strconv.ParseInt(value, 0, 0)
if err != nil {
return 0, err
}
return int(rst), nil
}
func toDuration(value string) (time.Duration, error) {
rst, err := time.ParseDuration(value)
if err != nil {
return 0, err
}
return rst, nil
}