aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrégoire Duchêne <gduchene@awhk.org>2023-02-26 13:12:55 +0000
committerGrégoire Duchêne <gduchene@awhk.org>2023-02-26 13:12:55 +0000
commit1ccf64c35e6cd5b335f8b230844712b6fb026dca (patch)
treef01e7d0885ea21a7cdca0714cd863bfde60e5064
parent7819ffd61f780eded638be342b469a57596a15fe (diff)
Parameterize UnknownEnumValueError
Also, do not sort the expected values in UnknownEnumValueError.Error.
-rw-r--r--flag.go22
-rw-r--r--flag_test.go13
2 files changed, 12 insertions, 23 deletions
diff --git a/flag.go b/flag.go
index 18d9f96..f9d048e 100644
--- a/flag.go
+++ b/flag.go
@@ -7,7 +7,6 @@ import (
"flag"
"fmt"
"os"
- "sort"
"strconv"
"strings"
"sync/atomic"
@@ -156,14 +155,10 @@ type ParseFunc[T any] func(string) (T, error)
// https://developers.google.com/protocol-buffers/docs/reference/go-generated#enum
// for more details.
func ParseProtobufEnum[T ~int32](values map[string]int32) ParseFunc[T] {
- valid := make([]string, 0, len(values))
- for val := range values {
- valid = append(valid, val)
- }
return func(s string) (T, error) {
val, found := values[strings.ToUpper(s)]
if !found {
- return 0, UnknownEnumValueError{s, valid}
+ return 0, UnknownEnumValueError[string]{s, MapKeys(values)}
}
return T(val), nil
}
@@ -185,7 +180,7 @@ func ParseStringEnum(values ...string) ParseFunc[string] {
return s, nil
}
}
- return "", UnknownEnumValueError{s, values}
+ return "", UnknownEnumValueError[string]{s, values}
}
}
@@ -197,18 +192,13 @@ func ParseTime(s string) (time.Time, error) {
// UnknownEnumValueError is returned by the functions produced by
// ParseProtobufEnum and ParseStringEnum when an unknown value is
// encountered.
-type UnknownEnumValueError struct {
+type UnknownEnumValueError[T any] struct {
Actual string
- Expected []string
+ Expected []T
}
-func (err UnknownEnumValueError) Error() string {
- // We sort the expected values so the output is deterministic, which may
- // be useful when parsing logs or otherwise examining program output.
- if !sort.StringsAreSorted(err.Expected) {
- sort.Strings(err.Expected)
- }
- return fmt.Sprintf("unknown value %s, expected one of %s", err.Actual, err.Expected)
+func (err UnknownEnumValueError[T]) Error() string {
+ return fmt.Sprintf("unknown value %s, expected one of %v", err.Actual, err.Expected)
}
type flagFeature struct{ *Feature }
diff --git a/flag_test.go b/flag_test.go
index 5b0df0e..3273775 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -5,10 +5,11 @@ package core_test
import (
"flag"
- "sort"
"strconv"
"testing"
+ "github.com/google/go-cmp/cmp"
+
"go.awhk.org/core"
)
@@ -144,7 +145,7 @@ func TestInitFlagSet(s *testing.T) {
}
func TestParseProtobufEnum(s *testing.T) {
- t := &core.T{T: s}
+ t := &core.T{T: s, Options: cmp.Options{sortStrings}}
// That type and map emulate code generated by protoc.
type fakeEnum int32
@@ -169,10 +170,9 @@ func TestParseProtobufEnum(s *testing.T) {
t.Run("UnknownValue", func(t *core.T) {
val, err := parse("BAZ")
- var exp core.UnknownEnumValueError
+ var exp core.UnknownEnumValueError[string]
if t.AssertErrorAs(&exp, err) {
t.AssertEqual("BAZ", exp.Actual)
- sort.Strings(exp.Expected)
t.AssertEqual([]string{"BAR", "FAKE_UNKNOWN", "FOO"}, exp.Expected)
}
t.AssertEqual(fakeEnum(0), val)
@@ -195,11 +195,10 @@ func TestParseStringEnum(s *testing.T) {
t.Run("UnknownValue", func(t *core.T) {
val, err := parse("baz")
- var exp core.UnknownEnumValueError
+ var exp core.UnknownEnumValueError[string]
if t.AssertErrorAs(&exp, err) {
t.AssertEqual("baz", exp.Actual)
- sort.Strings(exp.Expected)
- t.AssertEqual([]string{"bar", "foo"}, exp.Expected)
+ t.AssertEqual([]string{"foo", "bar"}, exp.Expected)
}
t.AssertEqual("", val)
})