-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathvalue_scalar.go
89 lines (81 loc) · 3.1 KB
/
value_scalar.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
// Copyright 2022 Harald Albrecht.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package enumflag
import (
"github.com/spf13/cobra"
"golang.org/x/exp/constraints"
)
// unknown is the textual representation of an unknown enum value, that is, when
// the enum value to name mapping doesn't have any idea about a particular enum
// value.
const unknown = "<unknown>"
// enumScalar represents a mutable, single enumeration value that can be
// retrieved, set, and stringified.
type enumScalar[E constraints.Integer] struct {
v *E
nodefault bool // opts in to accepting a zero enum value as the "none"
}
// Get returns the scalar enum value.
func (s *enumScalar[E]) Get() any { return *s.v }
// Set the value to the new scalar enum value corresponding to the passed
// textual representation, using the additionally specified text-to-value
// mapping. If the specified textual representation doesn't match any of the
// defined ones, an error is returned instead and the value isn't changed.
func (s *enumScalar[E]) Set(val string, names enumMapper[E]) error {
enumcode, err := names.ValueOf(val)
if err != nil {
return err
}
*s.v = enumcode
return nil
}
// String returns the textual representation of the scalar enum value, using the
// specified text-to-value mapping.
//
// String will return "<unknown>" for undefined/unmapped enum values. If the
// enum flag has been created using [NewWithoutDefault], then an empty string is
// returned instead: in this case [spf13/cobra] will not show any default for
// the corresponding CLI flag.
//
// [spf13/cobra]: https://github.com/spf13/cobra
func (s *enumScalar[E]) String(names enumMapper[E]) string {
if ids := names.Lookup(*s.v); len(ids) > 0 {
return ids[0]
}
if *s.v == 0 && s.nodefault {
return ""
}
return unknown
}
// NewCompletor returns a cobra Completor that completes enum flag values.
// Please note that shell completion hasn't the notion of case sensitivity or
// insensitivity, so we cannot take this into account but instead return all
// available enum value names in their original form.
func (s *enumScalar[E]) NewCompletor(enums EnumIdentifiers[E], help Help[E]) Completor {
completions := []string{}
for enumval, enumnames := range enums {
helptext := ""
if text, ok := help[enumval]; ok {
helptext = "\t" + text
}
// complete not only the canonical enum value name, but also all other
// (alias) names.
for _, name := range enumnames {
completions = append(completions, name+helptext)
}
}
return func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return completions, cobra.ShellCompDirectiveNoFileComp
}
}