Skip to content

Commit

Permalink
feat: add bcp 47 language tag validator (#730)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuaslate committed Apr 7, 2021
1 parent 6824818 commit add373f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 1 deletion.
14 changes: 14 additions & 0 deletions baked_in.go
Expand Up @@ -18,6 +18,7 @@ import (
"unicode/utf8"

"golang.org/x/crypto/sha3"
"golang.org/x/text/language"

urn "github.com/leodido/go-urn"
)
Expand Down Expand Up @@ -188,6 +189,7 @@ var (
"iso3166_1_alpha2": isIso3166Alpha2,
"iso3166_1_alpha3": isIso3166Alpha3,
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
"bcp47_language_tag": isBCP47LanguageTag,
}
)

Expand Down Expand Up @@ -2286,3 +2288,15 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
}
return iso3166_1_alpha_numeric[code]
}

// isBCP47LanguageTag is the validation function for validating if the current field's value is a valid BCP 47 language tag, as parsed by language.Parse
func isBCP47LanguageTag(fl FieldLevel) bool {
field := fl.Field()

if field.Kind() == reflect.String {
_, err := language.Parse(field.String())
return err == nil
}

panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
9 changes: 8 additions & 1 deletion doc.go
Expand Up @@ -1221,14 +1221,21 @@ see: https://www.iso.org/iso-3166-country-codes.html
Usage: iso3166_1_alpha3
BCP 47 Language Tag
This validates that a string value is a valid BCP 47 language tag, as parsed by language.Parse.
More information on https://pkg.go.dev/golang.org/x/text/language
Usage: bcp47_language_tag
TimeZone
This validates that a string value is a valid time zone based on the time zone database present on the system.
Although empty value and Local value are allowed by time.LoadLocation golang function, they are not allowed by this validator.
More information on https://golang.org/pkg/time/#LoadLocation
Usage: timezone
Alias Validators and Tags
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -8,4 +8,5 @@ require (
github.com/go-playground/universal-translator v0.17.0
github.com/leodido/go-urn v1.2.0
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/text v0.3.2 // indirect
)
5 changes: 5 additions & 0 deletions go.sum
Expand Up @@ -10,17 +10,22 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
43 changes: 43 additions & 0 deletions validator_test.go
Expand Up @@ -11158,3 +11158,46 @@ func TestDurationType(t *testing.T) {
})
}
}

func TestBCP47LanguageTagValidation(t *testing.T) {
tests := []struct {
value string `validate:"bcp47_language_tag"`
tag string
expected bool
}{
{"en-US", "bcp47_language_tag", true},
{"en_GB", "bcp47_language_tag", true},
{"es", "bcp47_language_tag", true},
{"English", "bcp47_language_tag", false},
{"ESES", "bcp47_language_tag", false},
{"az-Cyrl-AZ", "bcp47_language_tag", true},
{"en-029", "bcp47_language_tag", true},
{"xog", "bcp47_language_tag", true},
}

validate := New()

for i, test := range tests {

errs := validate.Var(test.value, test.tag)

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d locale failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d locale failed Error: %s", i, errs)
} else {
val := getError(errs, "", "")
if val.Tag() != "bcp47_language_tag" {
t.Fatalf("Index: %d locale failed Error: %s", i, errs)
}
}
}
}

PanicMatches(t, func() {
_ = validate.Var(2, "bcp47_language_tag")
}, "Bad field type int")
}

0 comments on commit add373f

Please sign in to comment.