forked from pariz/gountries
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquery.go
164 lines (127 loc) · 3.66 KB
/
query.go
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package gountries
import (
"strings"
"sync"
)
// Query holds a reference to the QueryHolder struct
var queryInitOnce sync.Once
var queryInstance *Query
// Query contains queries for countries, cities, etc.
type Query struct {
Countries map[string]Country
NameToAlpha2 map[string]string
Alpha3ToAlpha2 map[string]string
NativeNameToAlpha2 map[string]string
}
// FindCountryByName finds a country by given name
func (q *Query) FindCountryByName(name string) (result Country, err error) {
lowerName := strings.ToLower(name)
alpha2, exists := q.NameToAlpha2[lowerName]
if !exists {
return Country{}, makeError("Could not find country with name", name)
}
return q.Countries[alpha2], nil
}
// FindCountryByNativeName
func (q *Query) FindCountryByNativeName(name string) (result Country, err error) {
lowerName := strings.ToLower(name)
alpha2, exists := q.NativeNameToAlpha2[lowerName]
if !exists {
return Country{}, makeError("Could not find country with native name", name)
}
return q.Countries[alpha2], nil
}
// FindCountryByAlpha fincs a country by given code
func (q *Query) FindCountryByAlpha(code string) (result Country, err error) {
codeU := strings.ToUpper(code)
switch {
case len(code) == 2:
country, exists := q.Countries[codeU]
if !exists {
return Country{}, makeError("Could not find country with code %s", code)
}
return country, nil
case len(code) == 3:
alpha2, exists := q.Alpha3ToAlpha2[codeU]
if !exists {
return Country{}, makeError("Could not find country with code", code)
}
return q.Countries[alpha2], nil
default:
return Country{}, makeError("Invalid code format", code)
}
}
// FindAllCountries returns a list of all countries
func (q *Query) FindAllCountries() (countries map[string]Country) {
return q.Countries
}
// FindCountries finds a Country based on the given struct data
func (q Query) FindCountries(c Country) (countries []Country) {
for _, country := range q.Countries {
// Name
//
if c.Name.Common != "" && strings.ToLower(c.Name.Common) == strings.ToLower(country.Name.Common) {
continue
}
// Alpha
//
if c.Alpha2 != "" && c.Alpha2 != country.Alpha2 {
continue
}
if c.Alpha3 != "" && c.Alpha3 != country.Alpha3 {
continue
}
// Geo
//
if c.Geo.Continent != "" && strings.ToLower(c.Geo.Continent) != strings.ToLower(country.Geo.Continent) {
continue
}
if c.Geo.Region != "" && strings.ToLower(c.Geo.Region) != strings.ToLower(country.Geo.Region) {
continue
}
if c.Geo.SubRegion != "" && strings.ToLower(c.Geo.SubRegion) != strings.ToLower(country.Geo.SubRegion) {
continue
}
// Misc
//
if c.InternationalPrefix != "" && strings.ToLower(c.InternationalPrefix) != strings.ToLower(country.InternationalPrefix) {
continue
}
// Bordering countries
//
allMatch := false
if len(c.BorderingCountries()) > 0 {
for _, c1 := range c.BorderingCountries() {
match := false
for _, c2 := range country.BorderingCountries() {
match = c1.Alpha2 == c2.Alpha2
if match == true {
break
}
}
if match == true {
allMatch = true
} else {
allMatch = false
break
}
}
if allMatch == false {
continue
}
}
// Append if all matches
//
countries = append(countries, country)
}
return
}
// FindSubdivisionCountryByName finds the country of a given subdivision name
func (q *Query) FindSubdivisionCountryByName(subdivisionName string) (result Country, err error) {
for _, country := range q.Countries {
if _, ok := country.nameToSubdivision[strings.ToLower(subdivisionName)]; ok {
return country, nil
}
}
return Country{}, makeError("Invalid subdivision name", subdivisionName)
}