-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflags.go
More file actions
87 lines (77 loc) · 2.49 KB
/
flags.go
File metadata and controls
87 lines (77 loc) · 2.49 KB
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
// Copyright (c) 2026 Paweł Zaremba
// SPDX-License-Identifier: MIT
package x
import (
"encoding"
"flag"
"fmt"
"time"
)
// FlagsParse parses command-line arguments into a flag.FlagSet,
// applying customizations via provided FlagOption functions.
func FlagsParse(args []string, extras ...FlagOption) error {
return flagSet(extras...).Parse(args)
}
// FlagOption is a function type used to customize a flag.FlagSet during its initialization.
type FlagOption func(*flag.FlagSet)
// flagSet creates a new flag.FlagSet.
func flagSet(extras ...FlagOption) *flag.FlagSet {
flags := flag.NewFlagSet("", flag.ExitOnError)
for _, e := range extras {
e(flags)
}
return flags
}
// FlagSetName changes the name in the flag.FlagSet.
func FlagSetName(name string) FlagOption {
return func(flags *flag.FlagSet) {
flags.Init(name, flags.ErrorHandling())
}
}
// FlagSetErrorHandling changes the name in the flag.FlagSet.
func FlagSetErrorHandling(errorHandling flag.ErrorHandling) FlagOption {
return func(flags *flag.FlagSet) {
flags.Init(flags.Name(), errorHandling)
}
}
// primitives is a type constraint that holds all primitive types supported by [flag]
// and time.Duration.
type primitives interface {
bool | int | int64 | uint | uint64 | string | float64 |
time.Duration
}
func Flag[T primitives](p *T, name string, value T, usage string) FlagOption {
return func(flags *flag.FlagSet) {
switch v := any(p).(type) {
case *bool:
flags.BoolVar(v, name, (any(value)).(bool), usage)
case *int:
flags.IntVar(v, name, (any(value)).(int), usage)
case *int64:
flags.Int64Var(v, name, (any(value)).(int64), usage)
case *uint:
flags.UintVar(v, name, (any(value)).(uint), usage)
case *uint64:
flags.Uint64Var(v, name, (any(value)).(uint64), usage)
case *string:
flags.StringVar(v, name, (any(value)).(string), usage)
case *float64:
flags.Float64Var(v, name, (any(value)).(float64), usage)
case *time.Duration:
flags.DurationVar(v, name, (any(value)).(time.Duration), usage)
default:
panic(fmt.Sprintf("unsupported type: %T", v))
}
}
}
func FlagInt(p *int, name string, value int, usage string) FlagOption {
return func(flags *flag.FlagSet) {
flags.IntVar(p, name, value, usage)
}
}
// FlagText defines a flag with a custom TextMarshaler and TextUnmarshaler to parse and format its value.
func FlagText(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) FlagOption {
return func(flags *flag.FlagSet) {
flags.TextVar(p, name, value, usage)
}
}