Adds ability to validate oneof for space separated strings

Fixes Or Enhances https://github.com/go-playground/validator/issues/525.

**Make sure that you've checked the boxes below before you submit PR:**
- [x] Tests exist or have been written that cover this particular change.

Change Details:

* Adds the ability to match on space separated strings when using the
`oneof` validation. Space separted strings must be surrounded by single
quotes to be validated as one string. For example:

```
oneof='Awaiting Verification' 'Verified' 'Failed Verification'
```

passes validation for a field that is exactly `Failed Verification`
(though just `Failed` would...fail).

@go-playground/admins
pull/541/head
Jonathan Thom 5 years ago
parent dbbe6958b3
commit 432c17028a
No known key found for this signature in database
GPG Key ID: B6E703AC3AD25FFE
  1. 7
      baked_in.go
  2. 6
      doc.go
  3. 5
      validator_test.go

@ -9,6 +9,7 @@ import (
"net/url" "net/url"
"os" "os"
"reflect" "reflect"
"regexp"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -177,7 +178,8 @@ func parseOneOfParam2(s string) []string {
oneofValsCacheRWLock.RUnlock() oneofValsCacheRWLock.RUnlock()
if !ok { if !ok {
oneofValsCacheRWLock.Lock() oneofValsCacheRWLock.Lock()
vals = strings.Fields(s) re := regexp.MustCompile(`'[^']*'|\S+`)
vals = re.FindAllString(s, -1)
oneofValsCache[s] = vals oneofValsCache[s] = vals
oneofValsCacheRWLock.Unlock() oneofValsCacheRWLock.Unlock()
} }
@ -213,7 +215,8 @@ func isOneOf(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface())) panic(fmt.Sprintf("Bad field type %T", field.Interface()))
} }
for i := 0; i < len(vals); i++ { for i := 0; i < len(vals); i++ {
if vals[i] == v { val := strings.Replace(vals[i], "'", "", -1)
if val == v {
return true return true
} }
} }

@ -361,10 +361,12 @@ One Of
For strings, ints, and uints, oneof will ensure that the value For strings, ints, and uints, oneof will ensure that the value
is one of the values in the parameter. The parameter should be is one of the values in the parameter. The parameter should be
a list of values separated by whitespace. Values may be a list of values separated by whitespace. Values may be
strings or numbers. strings or numbers. To match strings with spaces in them, include
the target string between single quotes.
Usage: oneof=red green Usage: oneof=red green
oneof='red green' 'blue yellow'
oneof=5 7 9 oneof=5 7 9
Greater Than Greater Than

@ -14,11 +14,11 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/locales/en" "github.com/go-playground/locales/en"
"github.com/go-playground/locales/fr" "github.com/go-playground/locales/fr"
"github.com/go-playground/locales/nl" "github.com/go-playground/locales/nl"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
) )
// NOTES: // NOTES:
@ -4484,6 +4484,8 @@ func TestOneOfValidation(t *testing.T) {
}{ }{
{f: "red", t: "oneof=red green"}, {f: "red", t: "oneof=red green"},
{f: "green", t: "oneof=red green"}, {f: "green", t: "oneof=red green"},
{f: "red green", t: "oneof='red green' blue"},
{f: "blue", t: "oneof='red green' blue"},
{f: 5, t: "oneof=5 6"}, {f: 5, t: "oneof=5 6"},
{f: 6, t: "oneof=5 6"}, {f: 6, t: "oneof=5 6"},
{f: int8(6), t: "oneof=5 6"}, {f: int8(6), t: "oneof=5 6"},
@ -4509,6 +4511,7 @@ func TestOneOfValidation(t *testing.T) {
}{ }{
{f: "", t: "oneof=red green"}, {f: "", t: "oneof=red green"},
{f: "yellow", t: "oneof=red green"}, {f: "yellow", t: "oneof=red green"},
{f: "green", t: "oneof='red green' blue"},
{f: 5, t: "oneof=red green"}, {f: 5, t: "oneof=red green"},
{f: 6, t: "oneof=red green"}, {f: 6, t: "oneof=red green"},
{f: 6, t: "oneof=7"}, {f: 6, t: "oneof=7"},

Loading…
Cancel
Save