diff --git a/README.md b/README.md index ad39ca6..c8502f9 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,19 @@ import "cattlecloud.net/go/forms" ```go var ( - name string - age int + name string + age int + aliases []string + worth float64 + password *conceal.Text ) err := forms.Parse(request, forms.Schema{ - "NAME": forms.String(&name), - "AGE": forms.Int(&age), + "name": forms.String(&name), + "age": forms.Int(&age), + "aliases": forms.Strings(&aliases), + "worth": forms.Float64(&worth), + "password": forms.Secret(&pword), }) ``` diff --git a/forms.go b/forms.go index cfda088..f0ab38b 100644 --- a/forms.go +++ b/forms.go @@ -13,6 +13,7 @@ import ( "strconv" "github.com/shoenig/go-conceal" + "github.com/shoenig/lang" ) var ( @@ -104,6 +105,31 @@ func StringOr[T StringType](s *T, alt T) Parser { } } +type stringsParser[T StringType] struct { + required bool + destination *[]T +} + +func (p *stringsParser[T]) Parse(values []string) error { + switch { + case len(values) == 0 && p.required: + return ErrNoValue + case len(values) == 0: + return nil + default: + *p.destination = lang.Map(values, func(s string) T { return T(s) }) + } + return nil +} + +// Strings is used to extract a form data value into a slice of Go strings. +func Strings[T StringType](s *[]T) Parser { + return &stringsParser[T]{ + required: true, + destination: s, + } +} + // Secret is used to extract a form data value into a Go conceal.Text. If the // value is missing then an error is returned during parsing. func Secret(s **conceal.Text) Parser { diff --git a/forms_test.go b/forms_test.go index cff1f2d..67c95b6 100644 --- a/forms_test.go +++ b/forms_test.go @@ -363,3 +363,19 @@ func Test_Parse_IntType_IntOr(t *testing.T) { must.NoError(t, err) must.Eq(t, 100, age) } + +func Test_Parse_StringType_Strings(t *testing.T) { + t.Parallel() + + data := url.Values{ + "names": []string{"alice", "bob", "carol"}, + } + + var names []string + + err := ParseValues(data, Schema{ + "names": Strings(&names), + }) + must.NoError(t, err) + must.Eq(t, []string{"alice", "bob", "carol"}, names) +} diff --git a/go.mod b/go.mod index 168c0e8..e78a874 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.23 require ( github.com/shoenig/go-conceal v0.5.4 + github.com/shoenig/lang v0.0.6 github.com/shoenig/test v1.12.2 ) diff --git a/go.sum b/go.sum index bbfa9d5..4b14e5a 100644 --- a/go.sum +++ b/go.sum @@ -2,5 +2,7 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/shoenig/go-conceal v0.5.4 h1:xLzarDUw3vUJjz+DirzO58yijkX4I9F1KA+RPZMLGLY= github.com/shoenig/go-conceal v0.5.4/go.mod h1:LXmjZn/bO1Nrtvfex4VNbKViVE+aMhVvskZx8o7HBfs= +github.com/shoenig/lang v0.0.6 h1:i8NVe+fNQLUGXk+KPP6lB6Jcfmcrmc9nCEYknHsBbVQ= +github.com/shoenig/lang v0.0.6/go.mod h1:DStvcG5yPYr/xBBcTEaousm+Pqjn9ozAKfyqWwfhj34= github.com/shoenig/test v1.12.2 h1:ZVT8NeIUwGWpZcKaepPmFMoNQ3sVpxvqUh/MAqwFiJI= github.com/shoenig/test v1.12.2/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI=