aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrégoire Duchêne <gduchene@awhk.org>2023-10-07 16:06:00 +0100
committerGrégoire Duchêne <gduchene@awhk.org>2023-10-07 16:06:00 +0100
commit5262c1922b5d20b9f40a01579cfcff0351d21195 (patch)
tree0fdacfa675fa54c4508c017f3b7336bfebb19e4f
parentad0306e9e79df26146ee8c74531574385f461f81 (diff)
Add ParseStringRegexpv0.7.0
-rw-r--r--flag.go19
-rw-r--r--flag_test.go22
2 files changed, 41 insertions, 0 deletions
diff --git a/flag.go b/flag.go
index 7255802..7db895b 100644
--- a/flag.go
+++ b/flag.go
@@ -4,15 +4,22 @@
package core
import (
+ "errors"
"flag"
"fmt"
"os"
+ "regexp"
"strconv"
"strings"
"sync/atomic"
"time"
)
+// ErrStringRegexpNoMatch is an error wrapped and returned by functions
+// created by ParseStringRegexp if the string passed did not match the
+// regular expression used.
+var ErrStringRegexpNoMatch = errors.New("string did not match regexp")
+
// Flag works like other flag.FlagSet methods, except it is generic. The
// passed ParseFunc will be used to parse raw arguments into a useful T
// value. A valid *T is returned for use by the caller.
@@ -182,6 +189,18 @@ func ParseStringEnum(values ...string) ParseFunc[string] {
}
}
+// ParseStringRegexp returns a ParseFunc that will return the string
+// passed if it matches the regular expression.
+func ParseStringRegexp(r *regexp.Regexp) ParseFunc[string] {
+ err := fmt.Errorf("%w %q", ErrStringRegexpNoMatch, r)
+ return func(s string) (string, error) {
+ if !r.MatchString(s) {
+ return "", err
+ }
+ return s, nil
+ }
+}
+
// ParseStringerEnum returns a ParseFunc that will return the first
// value having a string value matching the string passed.
func ParseStringerEnum[T fmt.Stringer](values ...T) ParseFunc[T] {
diff --git a/flag_test.go b/flag_test.go
index 411174a..e5469d7 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -5,6 +5,7 @@ package core_test
import (
"flag"
+ "regexp"
"strconv"
"testing"
@@ -204,6 +205,27 @@ func TestParseStringEnum(s *testing.T) {
})
}
+func TestParseStringRegexp(s *testing.T) {
+ t := &core.T{T: s}
+ parse := core.ParseStringRegexp(regexp.MustCompile("Hello( World!)?"))
+
+ t.Run("Match", func(t *core.T) {
+ val, err := parse("Hello")
+ t.AssertErrorIs(nil, err)
+ t.AssertEqual("Hello", val)
+
+ val, err = parse("Hello World!")
+ t.AssertErrorIs(nil, err)
+ t.AssertEqual("Hello World!", val)
+ })
+
+ t.Run("NoMatch", func(t *core.T) {
+ val, err := parse("something else")
+ t.AssertErrorIs(core.ErrStringRegexpNoMatch, err)
+ t.AssertEqual("", val)
+ })
+}
+
func TestParseStringerEnum(s *testing.T) {
t := &core.T{T: s, Options: cmp.Options{fakeEnumComparer}}
parser := core.ParseStringerEnum(fakeEnumFoo, fakeEnumBar)