Skip to content

Commit 610b713

Browse files
authored
Add EU countries validator (#1252)
## 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
1 parent 5187f87 commit 610b713

File tree

3 files changed

+188
-2
lines changed

3 files changed

+188
-2
lines changed

baked_in.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ var (
6464
// defines a common or complex set of validation(s) to simplify
6565
// adding validation to structs.
6666
bakedInAliases = map[string]string{
67-
"iscolor": "hexcolor|rgb|rgba|hsl|hsla",
68-
"country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
67+
"iscolor": "hexcolor|rgb|rgba|hsl|hsla",
68+
"country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
69+
"eu_country_code": "iso3166_1_alpha2_eu|iso3166_1_alpha3_eu|iso3166_1_alpha_numeric_eu",
6970
}
7071

7172
// bakedInValidators is the default map of ValidationFunc
@@ -217,8 +218,11 @@ var (
217218
"datetime": isDatetime,
218219
"timezone": isTimeZone,
219220
"iso3166_1_alpha2": isIso3166Alpha2,
221+
"iso3166_1_alpha2_eu": isIso3166Alpha2EU,
220222
"iso3166_1_alpha3": isIso3166Alpha3,
223+
"iso3166_1_alpha3_eu": isIso3166Alpha3EU,
221224
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
225+
"iso3166_1_alpha_numeric_eu": isIso3166AlphaNumericEU,
222226
"iso3166_2": isIso31662,
223227
"iso4217": isIso4217,
224228
"iso4217_numeric": isIso4217Numeric,
@@ -2768,12 +2772,24 @@ func isIso3166Alpha2(fl FieldLevel) bool {
27682772
return iso3166_1_alpha2[val]
27692773
}
27702774

2775+
// isIso3166Alpha2EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 European Union country code.
2776+
func isIso3166Alpha2EU(fl FieldLevel) bool {
2777+
val := fl.Field().String()
2778+
return iso3166_1_alpha2_eu[val]
2779+
}
2780+
27712781
// isIso3166Alpha3 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
27722782
func isIso3166Alpha3(fl FieldLevel) bool {
27732783
val := fl.Field().String()
27742784
return iso3166_1_alpha3[val]
27752785
}
27762786

2787+
// isIso3166Alpha3EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 European Union country code.
2788+
func isIso3166Alpha3EU(fl FieldLevel) bool {
2789+
val := fl.Field().String()
2790+
return iso3166_1_alpha3_eu[val]
2791+
}
2792+
27772793
// isIso3166AlphaNumeric is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
27782794
func isIso3166AlphaNumeric(fl FieldLevel) bool {
27792795
field := fl.Field()
@@ -2796,6 +2812,28 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
27962812
return iso3166_1_alpha_numeric[code]
27972813
}
27982814

2815+
// isIso3166AlphaNumericEU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric European Union country code.
2816+
func isIso3166AlphaNumericEU(fl FieldLevel) bool {
2817+
field := fl.Field()
2818+
2819+
var code int
2820+
switch field.Kind() {
2821+
case reflect.String:
2822+
i, err := strconv.Atoi(field.String())
2823+
if err != nil {
2824+
return false
2825+
}
2826+
code = i % 1000
2827+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
2828+
code = int(field.Int() % 1000)
2829+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
2830+
code = int(field.Uint() % 1000)
2831+
default:
2832+
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
2833+
}
2834+
return iso3166_1_alpha_numeric_eu[code]
2835+
}
2836+
27992837
// isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
28002838
func isIso31662(fl FieldLevel) bool {
28012839
val := fl.Field().String()

country_codes.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ var iso3166_1_alpha2 = map[string]bool{
5454
"EH": true, "YE": true, "ZM": true, "ZW": true, "XK": true,
5555
}
5656

57+
var iso3166_1_alpha2_eu = map[string]bool{
58+
"AT": true, "BE": true, "BG": true, "HR": true, "CY": true,
59+
"CZ": true, "DK": true, "EE": true, "FI": true, "FR": true,
60+
"DE": true, "GR": true, "HU": true, "IE": true, "IT": true,
61+
"LV": true, "LT": true, "LU": true, "MT": true, "NL": true,
62+
"PL": true, "PT": true, "RO": true, "SK": true, "SI": true,
63+
"ES": true, "SE": true,
64+
}
65+
5766
var iso3166_1_alpha3 = map[string]bool{
5867
// see: https://www.iso.org/iso-3166-country-codes.html
5968
"AFG": true, "ALB": true, "DZA": true, "ASM": true, "AND": true,
@@ -107,6 +116,15 @@ var iso3166_1_alpha3 = map[string]bool{
107116
"VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true,
108117
"YEM": true, "ZMB": true, "ZWE": true, "ALA": true, "UNK": true,
109118
}
119+
120+
var iso3166_1_alpha3_eu = map[string]bool{
121+
"AUT": true, "BEL": true, "BGR": true, "HRV": true, "CYP": true,
122+
"CZE": true, "DNK": true, "EST": true, "FIN": true, "FRA": true,
123+
"DEU": true, "GRC": true, "HUN": true, "IRL": true, "ITA": true,
124+
"LVA": true, "LTU": true, "LUX": true, "MLT": true, "NLD": true,
125+
"POL": true, "PRT": true, "ROU": true, "SVK": true, "SVN": true,
126+
"ESP": true, "SWE": true,
127+
}
110128
var iso3166_1_alpha_numeric = map[int]bool{
111129
// see: https://www.iso.org/iso-3166-country-codes.html
112130
4: true, 8: true, 12: true, 16: true, 20: true,
@@ -161,6 +179,15 @@ var iso3166_1_alpha_numeric = map[int]bool{
161179
887: true, 894: true, 716: true, 248: true, 153: true,
162180
}
163181

182+
var iso3166_1_alpha_numeric_eu = map[int]bool{
183+
40: true, 56: true, 100: true, 191: true, 196: true,
184+
200: true, 208: true, 233: true, 246: true, 250: true,
185+
276: true, 300: true, 348: true, 372: true, 380: true,
186+
428: true, 440: true, 442: true, 470: true, 528: true,
187+
616: true, 620: true, 642: true, 703: true, 705: true,
188+
724: true, 752: true,
189+
}
190+
164191
var iso3166_2 = map[string]bool{
165192
"AD-02": true, "AD-03": true, "AD-04": true, "AD-05": true, "AD-06": true,
166193
"AD-07": true, "AD-08": true, "AE-AJ": true, "AE-AZ": true, "AE-DU": true,

validator_test.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12516,6 +12516,33 @@ func TestIsIso3166Alpha2Validation(t *testing.T) {
1251612516
}
1251712517
}
1251812518

12519+
func TestIsIso3166Alpha2EUValidation(t *testing.T) {
12520+
tests := []struct {
12521+
value string `validate:"iso3166_1_alpha2_eu"`
12522+
expected bool
12523+
}{
12524+
{"SE", true},
12525+
{"UK", false},
12526+
}
12527+
12528+
validate := New()
12529+
12530+
for i, test := range tests {
12531+
12532+
errs := validate.Var(test.value, "iso3166_1_alpha2_eu")
12533+
12534+
if test.expected {
12535+
if !IsEqual(errs, nil) {
12536+
t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
12537+
}
12538+
} else {
12539+
if IsEqual(errs, nil) {
12540+
t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
12541+
}
12542+
}
12543+
}
12544+
}
12545+
1251912546
func TestIsIso31662Validation(t *testing.T) {
1252012547
tests := []struct {
1252112548
value string `validate:"iso3166_2"`
@@ -12572,6 +12599,34 @@ func TestIsIso3166Alpha3Validation(t *testing.T) {
1257212599
}
1257312600
}
1257412601

12602+
func TestIsIso3166Alpha3EUValidation(t *testing.T) {
12603+
tests := []struct {
12604+
value string `validate:"iso3166_1_alpha3_eu"`
12605+
expected bool
12606+
}{
12607+
{"POL", true},
12608+
{"SWE", true},
12609+
{"UNK", false},
12610+
}
12611+
12612+
validate := New()
12613+
12614+
for i, test := range tests {
12615+
12616+
errs := validate.Var(test.value, "iso3166_1_alpha3_eu")
12617+
12618+
if test.expected {
12619+
if !IsEqual(errs, nil) {
12620+
t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
12621+
}
12622+
} else {
12623+
if IsEqual(errs, nil) {
12624+
t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
12625+
}
12626+
}
12627+
}
12628+
}
12629+
1257512630
func TestIsIso3166AlphaNumericValidation(t *testing.T) {
1257612631
tests := []struct {
1257712632
value interface{}
@@ -12607,6 +12662,39 @@ func TestIsIso3166AlphaNumericValidation(t *testing.T) {
1260712662
}, "Bad field type []string")
1260812663
}
1260912664

12665+
func TestIsIso3166AlphaNumericEUValidation(t *testing.T) {
12666+
tests := []struct {
12667+
value interface{}
12668+
expected bool
12669+
}{
12670+
{752, true}, //Sweden
12671+
{"752", true},
12672+
{826, false}, // UK
12673+
{"826", false},
12674+
}
12675+
12676+
validate := New()
12677+
12678+
for i, test := range tests {
12679+
12680+
errs := validate.Var(test.value, "iso3166_1_alpha_numeric_eu")
12681+
12682+
if test.expected {
12683+
if !IsEqual(errs, nil) {
12684+
t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
12685+
}
12686+
} else {
12687+
if IsEqual(errs, nil) {
12688+
t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
12689+
}
12690+
}
12691+
}
12692+
12693+
PanicMatches(t, func() {
12694+
_ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric_eu")
12695+
}, "Bad field type []string")
12696+
}
12697+
1261012698
func TestCountryCodeValidation(t *testing.T) {
1261112699
tests := []struct {
1261212700
value interface{}
@@ -12640,6 +12728,39 @@ func TestCountryCodeValidation(t *testing.T) {
1264012728
}
1264112729
}
1264212730

12731+
func TestEUCountryCodeValidation(t *testing.T) {
12732+
tests := []struct {
12733+
value interface{}
12734+
expected bool
12735+
}{
12736+
{724, true},
12737+
{0, false},
12738+
{1, false},
12739+
{"POL", true},
12740+
{"NO", false},
12741+
{"724", true},
12742+
{"1", false},
12743+
{"0", false},
12744+
}
12745+
12746+
validate := New()
12747+
12748+
for i, test := range tests {
12749+
12750+
errs := validate.Var(test.value, "eu_country_code")
12751+
12752+
if test.expected {
12753+
if !IsEqual(errs, nil) {
12754+
t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
12755+
}
12756+
} else {
12757+
if IsEqual(errs, nil) {
12758+
t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
12759+
}
12760+
}
12761+
}
12762+
}
12763+
1264312764
func TestIsIso4217Validation(t *testing.T) {
1264412765
tests := []struct {
1264512766
value string `validate:"iso4217"`

0 commit comments

Comments
 (0)