Skip to content

Commit a53d64f

Browse files
vuon9Dean Karn
andauthored
Postcode validator for value and field (#759)
* Postcode validator for value and field * Add translation for postcode rules Co-authored-by: Dean Karn <[email protected]>
1 parent c206620 commit a53d64f

File tree

5 files changed

+537
-323
lines changed

5 files changed

+537
-323
lines changed

baked_in.go

Lines changed: 168 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -68,129 +68,131 @@ var (
6868
// you can add, remove or even replace items to suite your needs,
6969
// or even disregard and use your own map if so desired.
7070
bakedInValidators = map[string]Func{
71-
"required": hasValue,
72-
"required_if": requiredIf,
73-
"required_unless": requiredUnless,
74-
"required_with": requiredWith,
75-
"required_with_all": requiredWithAll,
76-
"required_without": requiredWithout,
77-
"required_without_all": requiredWithoutAll,
78-
"excluded_with": excludedWith,
79-
"excluded_with_all": excludedWithAll,
80-
"excluded_without": excludedWithout,
81-
"excluded_without_all": excludedWithoutAll,
82-
"isdefault": isDefault,
83-
"len": hasLengthOf,
84-
"min": hasMinOf,
85-
"max": hasMaxOf,
86-
"eq": isEq,
87-
"ne": isNe,
88-
"lt": isLt,
89-
"lte": isLte,
90-
"gt": isGt,
91-
"gte": isGte,
92-
"eqfield": isEqField,
93-
"eqcsfield": isEqCrossStructField,
94-
"necsfield": isNeCrossStructField,
95-
"gtcsfield": isGtCrossStructField,
96-
"gtecsfield": isGteCrossStructField,
97-
"ltcsfield": isLtCrossStructField,
98-
"ltecsfield": isLteCrossStructField,
99-
"nefield": isNeField,
100-
"gtefield": isGteField,
101-
"gtfield": isGtField,
102-
"ltefield": isLteField,
103-
"ltfield": isLtField,
104-
"fieldcontains": fieldContains,
105-
"fieldexcludes": fieldExcludes,
106-
"alpha": isAlpha,
107-
"alphanum": isAlphanum,
108-
"alphaunicode": isAlphaUnicode,
109-
"alphanumunicode": isAlphanumUnicode,
110-
"numeric": isNumeric,
111-
"number": isNumber,
112-
"hexadecimal": isHexadecimal,
113-
"hexcolor": isHEXColor,
114-
"rgb": isRGB,
115-
"rgba": isRGBA,
116-
"hsl": isHSL,
117-
"hsla": isHSLA,
118-
"e164": isE164,
119-
"email": isEmail,
120-
"url": isURL,
121-
"uri": isURI,
122-
"urn_rfc2141": isUrnRFC2141, // RFC 2141
123-
"file": isFile,
124-
"base64": isBase64,
125-
"base64url": isBase64URL,
126-
"contains": contains,
127-
"containsany": containsAny,
128-
"containsrune": containsRune,
129-
"excludes": excludes,
130-
"excludesall": excludesAll,
131-
"excludesrune": excludesRune,
132-
"startswith": startsWith,
133-
"endswith": endsWith,
134-
"startsnotwith": startsNotWith,
135-
"endsnotwith": endsNotWith,
136-
"isbn": isISBN,
137-
"isbn10": isISBN10,
138-
"isbn13": isISBN13,
139-
"eth_addr": isEthereumAddress,
140-
"btc_addr": isBitcoinAddress,
141-
"btc_addr_bech32": isBitcoinBech32Address,
142-
"uuid": isUUID,
143-
"uuid3": isUUID3,
144-
"uuid4": isUUID4,
145-
"uuid5": isUUID5,
146-
"uuid_rfc4122": isUUIDRFC4122,
147-
"uuid3_rfc4122": isUUID3RFC4122,
148-
"uuid4_rfc4122": isUUID4RFC4122,
149-
"uuid5_rfc4122": isUUID5RFC4122,
150-
"ascii": isASCII,
151-
"printascii": isPrintableASCII,
152-
"multibyte": hasMultiByteCharacter,
153-
"datauri": isDataURI,
154-
"latitude": isLatitude,
155-
"longitude": isLongitude,
156-
"ssn": isSSN,
157-
"ipv4": isIPv4,
158-
"ipv6": isIPv6,
159-
"ip": isIP,
160-
"cidrv4": isCIDRv4,
161-
"cidrv6": isCIDRv6,
162-
"cidr": isCIDR,
163-
"tcp4_addr": isTCP4AddrResolvable,
164-
"tcp6_addr": isTCP6AddrResolvable,
165-
"tcp_addr": isTCPAddrResolvable,
166-
"udp4_addr": isUDP4AddrResolvable,
167-
"udp6_addr": isUDP6AddrResolvable,
168-
"udp_addr": isUDPAddrResolvable,
169-
"ip4_addr": isIP4AddrResolvable,
170-
"ip6_addr": isIP6AddrResolvable,
171-
"ip_addr": isIPAddrResolvable,
172-
"unix_addr": isUnixAddrResolvable,
173-
"mac": isMAC,
174-
"hostname": isHostnameRFC952, // RFC 952
175-
"hostname_rfc1123": isHostnameRFC1123, // RFC 1123
176-
"fqdn": isFQDN,
177-
"unique": isUnique,
178-
"oneof": isOneOf,
179-
"html": isHTML,
180-
"html_encoded": isHTMLEncoded,
181-
"url_encoded": isURLEncoded,
182-
"dir": isDir,
183-
"json": isJSON,
184-
"hostname_port": isHostnamePort,
185-
"lowercase": isLowercase,
186-
"uppercase": isUppercase,
187-
"datetime": isDatetime,
188-
"timezone": isTimeZone,
189-
"iso3166_1_alpha2": isIso3166Alpha2,
190-
"iso3166_1_alpha3": isIso3166Alpha3,
191-
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
192-
"bcp47_language_tag": isBCP47LanguageTag,
193-
"bic": isIsoBicFormat,
71+
"required": hasValue,
72+
"required_if": requiredIf,
73+
"required_unless": requiredUnless,
74+
"required_with": requiredWith,
75+
"required_with_all": requiredWithAll,
76+
"required_without": requiredWithout,
77+
"required_without_all": requiredWithoutAll,
78+
"excluded_with": excludedWith,
79+
"excluded_with_all": excludedWithAll,
80+
"excluded_without": excludedWithout,
81+
"excluded_without_all": excludedWithoutAll,
82+
"isdefault": isDefault,
83+
"len": hasLengthOf,
84+
"min": hasMinOf,
85+
"max": hasMaxOf,
86+
"eq": isEq,
87+
"ne": isNe,
88+
"lt": isLt,
89+
"lte": isLte,
90+
"gt": isGt,
91+
"gte": isGte,
92+
"eqfield": isEqField,
93+
"eqcsfield": isEqCrossStructField,
94+
"necsfield": isNeCrossStructField,
95+
"gtcsfield": isGtCrossStructField,
96+
"gtecsfield": isGteCrossStructField,
97+
"ltcsfield": isLtCrossStructField,
98+
"ltecsfield": isLteCrossStructField,
99+
"nefield": isNeField,
100+
"gtefield": isGteField,
101+
"gtfield": isGtField,
102+
"ltefield": isLteField,
103+
"ltfield": isLtField,
104+
"fieldcontains": fieldContains,
105+
"fieldexcludes": fieldExcludes,
106+
"alpha": isAlpha,
107+
"alphanum": isAlphanum,
108+
"alphaunicode": isAlphaUnicode,
109+
"alphanumunicode": isAlphanumUnicode,
110+
"numeric": isNumeric,
111+
"number": isNumber,
112+
"hexadecimal": isHexadecimal,
113+
"hexcolor": isHEXColor,
114+
"rgb": isRGB,
115+
"rgba": isRGBA,
116+
"hsl": isHSL,
117+
"hsla": isHSLA,
118+
"e164": isE164,
119+
"email": isEmail,
120+
"url": isURL,
121+
"uri": isURI,
122+
"urn_rfc2141": isUrnRFC2141, // RFC 2141
123+
"file": isFile,
124+
"base64": isBase64,
125+
"base64url": isBase64URL,
126+
"contains": contains,
127+
"containsany": containsAny,
128+
"containsrune": containsRune,
129+
"excludes": excludes,
130+
"excludesall": excludesAll,
131+
"excludesrune": excludesRune,
132+
"startswith": startsWith,
133+
"endswith": endsWith,
134+
"startsnotwith": startsNotWith,
135+
"endsnotwith": endsNotWith,
136+
"isbn": isISBN,
137+
"isbn10": isISBN10,
138+
"isbn13": isISBN13,
139+
"eth_addr": isEthereumAddress,
140+
"btc_addr": isBitcoinAddress,
141+
"btc_addr_bech32": isBitcoinBech32Address,
142+
"uuid": isUUID,
143+
"uuid3": isUUID3,
144+
"uuid4": isUUID4,
145+
"uuid5": isUUID5,
146+
"uuid_rfc4122": isUUIDRFC4122,
147+
"uuid3_rfc4122": isUUID3RFC4122,
148+
"uuid4_rfc4122": isUUID4RFC4122,
149+
"uuid5_rfc4122": isUUID5RFC4122,
150+
"ascii": isASCII,
151+
"printascii": isPrintableASCII,
152+
"multibyte": hasMultiByteCharacter,
153+
"datauri": isDataURI,
154+
"latitude": isLatitude,
155+
"longitude": isLongitude,
156+
"ssn": isSSN,
157+
"ipv4": isIPv4,
158+
"ipv6": isIPv6,
159+
"ip": isIP,
160+
"cidrv4": isCIDRv4,
161+
"cidrv6": isCIDRv6,
162+
"cidr": isCIDR,
163+
"tcp4_addr": isTCP4AddrResolvable,
164+
"tcp6_addr": isTCP6AddrResolvable,
165+
"tcp_addr": isTCPAddrResolvable,
166+
"udp4_addr": isUDP4AddrResolvable,
167+
"udp6_addr": isUDP6AddrResolvable,
168+
"udp_addr": isUDPAddrResolvable,
169+
"ip4_addr": isIP4AddrResolvable,
170+
"ip6_addr": isIP6AddrResolvable,
171+
"ip_addr": isIPAddrResolvable,
172+
"unix_addr": isUnixAddrResolvable,
173+
"mac": isMAC,
174+
"hostname": isHostnameRFC952, // RFC 952
175+
"hostname_rfc1123": isHostnameRFC1123, // RFC 1123
176+
"fqdn": isFQDN,
177+
"unique": isUnique,
178+
"oneof": isOneOf,
179+
"html": isHTML,
180+
"html_encoded": isHTMLEncoded,
181+
"url_encoded": isURLEncoded,
182+
"dir": isDir,
183+
"json": isJSON,
184+
"hostname_port": isHostnamePort,
185+
"lowercase": isLowercase,
186+
"uppercase": isUppercase,
187+
"datetime": isDatetime,
188+
"timezone": isTimeZone,
189+
"iso3166_1_alpha2": isIso3166Alpha2,
190+
"iso3166_1_alpha3": isIso3166Alpha3,
191+
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
192+
"bcp47_language_tag": isBCP47LanguageTag,
193+
"postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2,
194+
"postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field,
195+
"bic": isIsoBicFormat,
194196
}
195197
)
196198

@@ -1205,6 +1207,49 @@ func isEq(fl FieldLevel) bool {
12051207
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
12061208
}
12071209

1210+
// isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2
1211+
// example: `postcode_iso3166_alpha2=US`
1212+
func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
1213+
field := fl.Field()
1214+
param := fl.Param()
1215+
1216+
reg, found := postCodeRegexDict[param]
1217+
if !found {
1218+
return false
1219+
}
1220+
1221+
return reg.MatchString(field.String())
1222+
}
1223+
1224+
// isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2
1225+
// example: `postcode_iso3166_alpha2_field=CountryCode`
1226+
func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
1227+
field := fl.Field()
1228+
kind := field.Kind()
1229+
1230+
params := parseOneOfParam2(fl.Param())
1231+
1232+
if len(params) != 1 {
1233+
return false
1234+
}
1235+
1236+
currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0])
1237+
if !found {
1238+
return false
1239+
}
1240+
1241+
if kind != reflect.String {
1242+
panic(fmt.Sprintf("Bad field type %T", currentField.Interface()))
1243+
}
1244+
1245+
reg, found := postCodeRegexDict[currentField.String()]
1246+
if !found {
1247+
return false
1248+
}
1249+
1250+
return reg.MatchString(field.String())
1251+
}
1252+
12081253
// IsBase64 is the validation function for validating if the current field's value is a valid base 64.
12091254
func isBase64(fl FieldLevel) bool {
12101255
return base64Regex.MatchString(fl.Field().String())

0 commit comments

Comments
 (0)