Skip to content

Commit

Permalink
Add EU countries validator (#1252)
Browse files Browse the repository at this point in the history
## Enhances


**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.

@go-playground/validator-maintainers
  • Loading branch information
masv3971 authored Apr 30, 2024
1 parent 5187f87 commit 610b713
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 2 deletions.
42 changes: 40 additions & 2 deletions baked_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ var (
// defines a common or complex set of validation(s) to simplify
// adding validation to structs.
bakedInAliases = map[string]string{
"iscolor": "hexcolor|rgb|rgba|hsl|hsla",
"country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
"iscolor": "hexcolor|rgb|rgba|hsl|hsla",
"country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
"eu_country_code": "iso3166_1_alpha2_eu|iso3166_1_alpha3_eu|iso3166_1_alpha_numeric_eu",
}

// bakedInValidators is the default map of ValidationFunc
Expand Down Expand Up @@ -217,8 +218,11 @@ var (
"datetime": isDatetime,
"timezone": isTimeZone,
"iso3166_1_alpha2": isIso3166Alpha2,
"iso3166_1_alpha2_eu": isIso3166Alpha2EU,
"iso3166_1_alpha3": isIso3166Alpha3,
"iso3166_1_alpha3_eu": isIso3166Alpha3EU,
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
"iso3166_1_alpha_numeric_eu": isIso3166AlphaNumericEU,
"iso3166_2": isIso31662,
"iso4217": isIso4217,
"iso4217_numeric": isIso4217Numeric,
Expand Down Expand Up @@ -2768,12 +2772,24 @@ func isIso3166Alpha2(fl FieldLevel) bool {
return iso3166_1_alpha2[val]
}

// isIso3166Alpha2EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 European Union country code.
func isIso3166Alpha2EU(fl FieldLevel) bool {
val := fl.Field().String()
return iso3166_1_alpha2_eu[val]
}

// isIso3166Alpha3 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
func isIso3166Alpha3(fl FieldLevel) bool {
val := fl.Field().String()
return iso3166_1_alpha3[val]
}

// isIso3166Alpha3EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 European Union country code.
func isIso3166Alpha3EU(fl FieldLevel) bool {
val := fl.Field().String()
return iso3166_1_alpha3_eu[val]
}

// isIso3166AlphaNumeric is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
func isIso3166AlphaNumeric(fl FieldLevel) bool {
field := fl.Field()
Expand All @@ -2796,6 +2812,28 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
return iso3166_1_alpha_numeric[code]
}

// isIso3166AlphaNumericEU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric European Union country code.
func isIso3166AlphaNumericEU(fl FieldLevel) bool {
field := fl.Field()

var code int
switch field.Kind() {
case reflect.String:
i, err := strconv.Atoi(field.String())
if err != nil {
return false
}
code = i % 1000
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
code = int(field.Int() % 1000)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
code = int(field.Uint() % 1000)
default:
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
return iso3166_1_alpha_numeric_eu[code]
}

// isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
func isIso31662(fl FieldLevel) bool {
val := fl.Field().String()
Expand Down
27 changes: 27 additions & 0 deletions country_codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ var iso3166_1_alpha2 = map[string]bool{
"EH": true, "YE": true, "ZM": true, "ZW": true, "XK": true,
}

var iso3166_1_alpha2_eu = map[string]bool{
"AT": true, "BE": true, "BG": true, "HR": true, "CY": true,
"CZ": true, "DK": true, "EE": true, "FI": true, "FR": true,
"DE": true, "GR": true, "HU": true, "IE": true, "IT": true,
"LV": true, "LT": true, "LU": true, "MT": true, "NL": true,
"PL": true, "PT": true, "RO": true, "SK": true, "SI": true,
"ES": true, "SE": true,
}

var iso3166_1_alpha3 = map[string]bool{
// see: https://www.iso.org/iso-3166-country-codes.html
"AFG": true, "ALB": true, "DZA": true, "ASM": true, "AND": true,
Expand Down Expand Up @@ -107,6 +116,15 @@ var iso3166_1_alpha3 = map[string]bool{
"VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true,
"YEM": true, "ZMB": true, "ZWE": true, "ALA": true, "UNK": true,
}

var iso3166_1_alpha3_eu = map[string]bool{
"AUT": true, "BEL": true, "BGR": true, "HRV": true, "CYP": true,
"CZE": true, "DNK": true, "EST": true, "FIN": true, "FRA": true,
"DEU": true, "GRC": true, "HUN": true, "IRL": true, "ITA": true,
"LVA": true, "LTU": true, "LUX": true, "MLT": true, "NLD": true,
"POL": true, "PRT": true, "ROU": true, "SVK": true, "SVN": true,
"ESP": true, "SWE": true,
}
var iso3166_1_alpha_numeric = map[int]bool{
// see: https://www.iso.org/iso-3166-country-codes.html
4: true, 8: true, 12: true, 16: true, 20: true,
Expand Down Expand Up @@ -161,6 +179,15 @@ var iso3166_1_alpha_numeric = map[int]bool{
887: true, 894: true, 716: true, 248: true, 153: true,
}

var iso3166_1_alpha_numeric_eu = map[int]bool{
40: true, 56: true, 100: true, 191: true, 196: true,
200: true, 208: true, 233: true, 246: true, 250: true,
276: true, 300: true, 348: true, 372: true, 380: true,
428: true, 440: true, 442: true, 470: true, 528: true,
616: true, 620: true, 642: true, 703: true, 705: true,
724: true, 752: true,
}

var iso3166_2 = map[string]bool{
"AD-02": true, "AD-03": true, "AD-04": true, "AD-05": true, "AD-06": true,
"AD-07": true, "AD-08": true, "AE-AJ": true, "AE-AZ": true, "AE-DU": true,
Expand Down
121 changes: 121 additions & 0 deletions validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12516,6 +12516,33 @@ func TestIsIso3166Alpha2Validation(t *testing.T) {
}
}

func TestIsIso3166Alpha2EUValidation(t *testing.T) {
tests := []struct {
value string `validate:"iso3166_1_alpha2_eu"`
expected bool
}{
{"SE", true},
{"UK", false},
}

validate := New()

for i, test := range tests {

errs := validate.Var(test.value, "iso3166_1_alpha2_eu")

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
}
}
}
}

func TestIsIso31662Validation(t *testing.T) {
tests := []struct {
value string `validate:"iso3166_2"`
Expand Down Expand Up @@ -12572,6 +12599,34 @@ func TestIsIso3166Alpha3Validation(t *testing.T) {
}
}

func TestIsIso3166Alpha3EUValidation(t *testing.T) {
tests := []struct {
value string `validate:"iso3166_1_alpha3_eu"`
expected bool
}{
{"POL", true},
{"SWE", true},
{"UNK", false},
}

validate := New()

for i, test := range tests {

errs := validate.Var(test.value, "iso3166_1_alpha3_eu")

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
}
}
}
}

func TestIsIso3166AlphaNumericValidation(t *testing.T) {
tests := []struct {
value interface{}
Expand Down Expand Up @@ -12607,6 +12662,39 @@ func TestIsIso3166AlphaNumericValidation(t *testing.T) {
}, "Bad field type []string")
}

func TestIsIso3166AlphaNumericEUValidation(t *testing.T) {
tests := []struct {
value interface{}
expected bool
}{
{752, true}, //Sweden
{"752", true},
{826, false}, // UK
{"826", false},
}

validate := New()

for i, test := range tests {

errs := validate.Var(test.value, "iso3166_1_alpha_numeric_eu")

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
}
}
}

PanicMatches(t, func() {
_ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric_eu")
}, "Bad field type []string")
}

func TestCountryCodeValidation(t *testing.T) {
tests := []struct {
value interface{}
Expand Down Expand Up @@ -12640,6 +12728,39 @@ func TestCountryCodeValidation(t *testing.T) {
}
}

func TestEUCountryCodeValidation(t *testing.T) {
tests := []struct {
value interface{}
expected bool
}{
{724, true},
{0, false},
{1, false},
{"POL", true},
{"NO", false},
{"724", true},
{"1", false},
{"0", false},
}

validate := New()

for i, test := range tests {

errs := validate.Var(test.value, "eu_country_code")

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
}
}
}
}

func TestIsIso4217Validation(t *testing.T) {
tests := []struct {
value string `validate:"iso4217"`
Expand Down

0 comments on commit 610b713

Please sign in to comment.