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
|
// SPDX-FileCopyrightText: © 2022 Grégoire Duchêne <gduchene@awhk.org>
// SPDX-License-Identifier: ISC
package core
import (
"flag"
"fmt"
"time"
)
func FlagVar[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T]) *T {
v := &flagValue[T]{Parse: parse, Value: new(T)}
fs.Var(v, name, usage)
return v.Value
}
func FlagVarDef[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], def T) *T {
val := def
FlagVarPtr(fs, name, usage, parse, &val)
return &val
}
func FlagVarPtr[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], val *T) {
fs.Var(&flagValue[T]{Parse: parse, Value: val}, name, usage)
}
func FlagVarSlice[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T]) *[]T {
v := &flagValueSlice[T]{Parse: parse, Values: new([]T)}
fs.Var(v, name, usage)
return v.Values
}
func FlagVarSliceDef[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], def []T) *[]T {
vals := make([]T, len(def))
copy(vals, def)
FlagVarSlicePtr(fs, name, usage, parse, &vals)
return &vals
}
func FlagVarSlicePtr[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], vals *[]T) {
fs.Var(&flagValueSlice[T]{Parse: parse, Values: vals}, name, usage)
}
// ParseString returns the string passed with no error set.
func ParseString(s string) (string, error) {
return s, nil
}
// ParseTime parses a string according to the time.RFC3339 format.
func ParseTime(s string) (time.Time, error) {
return time.Parse(time.RFC3339, s)
}
// ParseFunc describes functions that will parse a string and return a
// value or an error.
type ParseFunc[T any] func(string) (T, error)
type flagValue[T any] struct {
Parse ParseFunc[T]
Value *T
}
var _ flag.Value = &flagValue[any]{}
func (f *flagValue[T]) Set(s string) error {
val, err := f.Parse(s)
if err != nil {
return err
}
*f.Value = val
return nil
}
func (f *flagValue[T]) String() string {
return fmt.Sprintf("%v", f.Value)
}
type flagValueSlice[T any] struct {
Parse ParseFunc[T]
Values *[]T
shouldAppend bool
}
var _ flag.Value = &flagValueSlice[any]{}
func (f *flagValueSlice[T]) Set(s string) error {
val, err := f.Parse(s)
if err != nil {
return err
}
if f.shouldAppend {
*f.Values = append(*f.Values, val)
} else {
*f.Values = []T{val}
f.shouldAppend = true
}
return nil
}
func (f *flagValueSlice[T]) String() string {
return fmt.Sprintf("%v", f.Values)
}
|