-
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathpostcode.go
More file actions
76 lines (63 loc) · 1.72 KB
/
postcode.go
File metadata and controls
76 lines (63 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
Package postcode validates postal codes. While the validation process does
not guarantee that the postcode actually exists, it does guarantee that the
format of the provided input is valid.
For more information see:
https://en.wikipedia.org/wiki/List_of_postal_codes
https://en.wikipedia.org/wiki/ISO_3166-1
Example
if err := postcode.Validate("10007"); err != nil {
// the postcode is not valid
// treat error
}
*/
package postcode
import (
"errors"
"strings"
"unicode"
)
// Possible validation errors.
var (
ErrEmpty = errors.New("postal code cannot be empty")
ErrShort = errors.New("postal code cannot be shorter than 2 characters")
ErrInvalidCountry = errors.New("invalid country code")
ErrInvalidFormat = errors.New("invalid postal code format")
)
// Validate checks if the provided input string matches any of the
// accepted postcode formats. If the validation fails, the function returns
// an error specifying the cause.
func Validate(code string) error {
if code = strings.ToUpper(strings.TrimSpace(code)); code == "" {
return ErrEmpty
}
format := []rune(code)
if len(format) < 2 {
return ErrShort
}
// Map input postal code to format.
countryCode := string(format[:2])
for i, r := range format {
switch {
case unicode.IsDigit(r):
r = 'N'
case unicode.IsLetter(r):
r = 'A'
}
format[i] = r
}
if _, ok := formats[string(format)]; ok {
return nil
}
// Check if postal code is valid when accounting for the country code.
if format[0] == 'A' && format[1] == 'A' {
format[0], format[1] = 'C', 'C'
if _, ok := formats[string(format)]; ok {
if _, ok := countryCodes[countryCode]; !ok {
return ErrInvalidCountry
}
return nil
}
}
return ErrInvalidFormat
}