1package config
2
3import (
4	"strconv"
5	"strings"
6	"time"
7)
8
9// boolPtrValue is a flag.Value which stores the value in a *bool if it
10// can be parsed with strconv.ParseBool. If the value was not set the
11// pointer is nil.
12type boolPtrValue struct {
13	v **bool
14	b bool
15}
16
17func newBoolPtrValue(p **bool) *boolPtrValue {
18	return &boolPtrValue{p, false}
19}
20
21func (s *boolPtrValue) IsBoolFlag() bool { return true }
22
23func (s *boolPtrValue) Set(val string) error {
24	b, err := strconv.ParseBool(val)
25	if err != nil {
26		return err
27	}
28	*s.v, s.b = &b, true
29	return nil
30}
31
32func (s *boolPtrValue) Get() interface{} {
33	if s.b {
34		return *s.v
35	}
36	return (*bool)(nil)
37}
38
39func (s *boolPtrValue) String() string {
40	if s.b {
41		return strconv.FormatBool(**s.v)
42	}
43	return ""
44}
45
46// durationPtrValue is a flag.Value which stores the value in a
47// *time.Duration if it can be parsed with time.ParseDuration. If the
48// value was not set the pointer is nil.
49type durationPtrValue struct {
50	v **time.Duration
51	b bool
52}
53
54func newDurationPtrValue(p **time.Duration) *durationPtrValue {
55	return &durationPtrValue{p, false}
56}
57
58func (s *durationPtrValue) Set(val string) error {
59	d, err := time.ParseDuration(val)
60	if err != nil {
61		return err
62	}
63	*s.v, s.b = &d, true
64	return nil
65}
66
67func (s *durationPtrValue) Get() interface{} {
68	if s.b {
69		return *s.v
70	}
71	return (*time.Duration)(nil)
72}
73
74func (s *durationPtrValue) String() string {
75	if s.b {
76		return (*(*s).v).String()
77	}
78	return ""
79}
80
81// intPtrValue is a flag.Value which stores the value in a *int if it
82// can be parsed with strconv.Atoi. If the value was not set the pointer
83// is nil.
84type intPtrValue struct {
85	v **int
86	b bool
87}
88
89func newIntPtrValue(p **int) *intPtrValue {
90	return &intPtrValue{p, false}
91}
92
93func (s *intPtrValue) Set(val string) error {
94	n, err := strconv.Atoi(val)
95	if err != nil {
96		return err
97	}
98	*s.v, s.b = &n, true
99	return nil
100}
101
102func (s *intPtrValue) Get() interface{} {
103	if s.b {
104		return *s.v
105	}
106	return (*int)(nil)
107}
108
109func (s *intPtrValue) String() string {
110	if s.b {
111		return strconv.Itoa(**s.v)
112	}
113	return ""
114}
115
116// stringMapValue is a flag.Value which stores the value in a map[string]string if the
117// value is in "key:value" format. This can be specified multiple times.
118type stringMapValue map[string]string
119
120func newStringMapValue(p *map[string]string) *stringMapValue {
121	*p = map[string]string{}
122	return (*stringMapValue)(p)
123}
124
125func (s *stringMapValue) Set(val string) error {
126	p := strings.SplitN(val, ":", 2)
127	k, v := p[0], ""
128	if len(p) == 2 {
129		v = p[1]
130	}
131	(*s)[k] = v
132	return nil
133}
134
135func (s *stringMapValue) Get() interface{} {
136	return s
137}
138
139func (s *stringMapValue) String() string {
140	var x []string
141	for k, v := range *s {
142		if v == "" {
143			x = append(x, k)
144		} else {
145			x = append(x, k+":"+v)
146		}
147	}
148	return strings.Join(x, " ")
149}
150
151// stringPtrValue is a flag.Value which stores the value in a *string.
152// If the value was not set the pointer is nil.
153type stringPtrValue struct {
154	v **string
155	b bool
156}
157
158func newStringPtrValue(p **string) *stringPtrValue {
159	return &stringPtrValue{p, false}
160}
161
162func (s *stringPtrValue) Set(val string) error {
163	*s.v, s.b = &val, true
164	return nil
165}
166
167func (s *stringPtrValue) Get() interface{} {
168	if s.b {
169		return *s.v
170	}
171	return (*string)(nil)
172}
173
174func (s *stringPtrValue) String() string {
175	if s.b {
176		return **s.v
177	}
178	return ""
179}
180
181// stringSliceValue is a flag.Value which appends the value to a []string.
182// This can be specified multiple times.
183type stringSliceValue []string
184
185func newStringSliceValue(p *[]string) *stringSliceValue {
186	return (*stringSliceValue)(p)
187}
188
189func (s *stringSliceValue) Set(val string) error {
190	*s = append(*s, val)
191	return nil
192}
193
194func (s *stringSliceValue) Get() interface{} {
195	return s
196}
197
198func (s *stringSliceValue) String() string {
199	return strings.Join(*s, " ")
200}
201