2021-06-17 15:32:39 +05:30
|
|
|
// swiftlint:disable switch_case_on_newline
|
2021-09-27 03:49:50 +05:30
|
|
|
import Defaults
|
2021-06-17 15:32:39 +05:30
|
|
|
|
2021-09-27 03:49:50 +05:30
|
|
|
enum Country: String, CaseIterable, Identifiable, Hashable, Defaults.Serializable {
|
2021-06-17 15:32:39 +05:30
|
|
|
var id: String {
|
|
|
|
rawValue
|
|
|
|
}
|
|
|
|
|
2021-08-01 03:40:56 +05:30
|
|
|
func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(id)
|
|
|
|
}
|
|
|
|
|
2021-06-17 15:32:39 +05:30
|
|
|
case dz = "DZ"
|
|
|
|
case ar = "AR"
|
|
|
|
case au = "AU"
|
|
|
|
case at = "AT"
|
|
|
|
case az = "AZ"
|
|
|
|
case bh = "BH"
|
|
|
|
case bd = "BD"
|
|
|
|
case by = "BY"
|
|
|
|
case be = "BE"
|
|
|
|
case bo = "BO"
|
|
|
|
case ba = "BA"
|
|
|
|
case br = "BR"
|
|
|
|
case bg = "BG"
|
|
|
|
case ca = "CA"
|
|
|
|
case cl = "CL"
|
|
|
|
case co = "CO"
|
|
|
|
case cr = "CR"
|
|
|
|
case hr = "HR"
|
|
|
|
case cy = "CY"
|
|
|
|
case cz = "CZ"
|
|
|
|
case dk = "DK"
|
|
|
|
case `do` = "DO"
|
|
|
|
case ec = "EC"
|
|
|
|
case eg = "EG"
|
|
|
|
case sv = "SV"
|
|
|
|
case ee = "EE"
|
|
|
|
case fi = "FI"
|
|
|
|
case fr = "FR"
|
|
|
|
case ge = "GE"
|
|
|
|
case de = "DE"
|
|
|
|
case gh = "GH"
|
|
|
|
case gr = "GR"
|
|
|
|
case gt = "GT"
|
|
|
|
case hn = "HN"
|
|
|
|
case hk = "HK"
|
|
|
|
case hu = "HU"
|
|
|
|
case `is` = "IS"
|
|
|
|
case `in` = "IN"
|
|
|
|
case id = "ID"
|
|
|
|
case iq = "IQ"
|
|
|
|
case ie = "IE"
|
|
|
|
case il = "IL"
|
|
|
|
case it = "IT"
|
|
|
|
case jm = "JM"
|
|
|
|
case jp = "JP"
|
|
|
|
case jo = "JO"
|
|
|
|
case kz = "KZ"
|
|
|
|
case ke = "KE"
|
|
|
|
case kr = "KR"
|
|
|
|
case kw = "KW"
|
|
|
|
case lv = "LV"
|
|
|
|
case lb = "LB"
|
|
|
|
case ly = "LY"
|
|
|
|
case li = "LI"
|
|
|
|
case lt = "LT"
|
|
|
|
case lu = "LU"
|
|
|
|
case mk = "MK"
|
|
|
|
case my = "MY"
|
|
|
|
case mt = "MT"
|
|
|
|
case mx = "MX"
|
|
|
|
case me = "ME"
|
|
|
|
case ma = "MA"
|
|
|
|
case np = "NP"
|
|
|
|
case nl = "NL"
|
|
|
|
case nz = "NZ"
|
|
|
|
case ni = "NI"
|
|
|
|
case ng = "NG"
|
|
|
|
case no = "NO"
|
|
|
|
case om = "OM"
|
|
|
|
case pk = "PK"
|
|
|
|
case pa = "PA"
|
|
|
|
case pg = "PG"
|
|
|
|
case py = "PY"
|
|
|
|
case pe = "PE"
|
|
|
|
case ph = "PH"
|
|
|
|
case pl = "PL"
|
|
|
|
case pt = "PT"
|
|
|
|
case pr = "PR"
|
|
|
|
case qa = "QA"
|
|
|
|
case ro = "RO"
|
|
|
|
case ru = "RU"
|
|
|
|
case sa = "SA"
|
|
|
|
case sn = "SN"
|
|
|
|
case rs = "RS"
|
|
|
|
case sg = "SG"
|
|
|
|
case sk = "SK"
|
|
|
|
case si = "SI"
|
|
|
|
case za = "ZA"
|
|
|
|
case es = "ES"
|
|
|
|
case lk = "LK"
|
|
|
|
case se = "SE"
|
|
|
|
case ch = "CH"
|
|
|
|
case tw = "TW"
|
|
|
|
case tz = "TZ"
|
|
|
|
case th = "TH"
|
|
|
|
case tn = "TN"
|
|
|
|
case tr = "TR"
|
|
|
|
case ug = "UG"
|
|
|
|
case ua = "UA"
|
|
|
|
case ae = "AE"
|
|
|
|
case gb = "GB"
|
|
|
|
case us = "US"
|
|
|
|
case uy = "UY"
|
|
|
|
case ve = "VE"
|
|
|
|
case vn = "VN"
|
|
|
|
case vi = "VI"
|
|
|
|
case ye = "YE"
|
|
|
|
case zw = "ZW"
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Country {
|
|
|
|
var name: String {
|
|
|
|
switch self {
|
|
|
|
case .dz: return "Algeria"
|
|
|
|
case .ar: return "Argentina"
|
|
|
|
case .au: return "Australia"
|
|
|
|
case .at: return "Austria"
|
|
|
|
case .az: return "Azerbaijan"
|
|
|
|
case .bh: return "Bahrain"
|
|
|
|
case .bd: return "Bangladesh"
|
|
|
|
case .by: return "Belarus"
|
|
|
|
case .be: return "Belgium"
|
|
|
|
case .bo: return "Bolivia (Plurinational State of)"
|
|
|
|
case .ba: return "Bosnia and Herzegovina"
|
|
|
|
case .br: return "Brazil"
|
|
|
|
case .bg: return "Bulgaria"
|
|
|
|
case .ca: return "Canada"
|
|
|
|
case .cl: return "Chile"
|
|
|
|
case .co: return "Colombia"
|
|
|
|
case .cr: return "Costa Rica"
|
|
|
|
case .hr: return "Croatia"
|
|
|
|
case .cy: return "Cyprus"
|
|
|
|
case .cz: return "Czechia"
|
|
|
|
case .dk: return "Denmark"
|
|
|
|
case .do: return "Dominican Republic"
|
|
|
|
case .ec: return "Ecuador"
|
|
|
|
case .eg: return "Egypt"
|
|
|
|
case .sv: return "El Salvador"
|
|
|
|
case .ee: return "Estonia"
|
|
|
|
case .fi: return "Finland"
|
|
|
|
case .fr: return "France"
|
|
|
|
case .ge: return "Georgia"
|
|
|
|
case .de: return "Germany"
|
|
|
|
case .gh: return "Ghana"
|
|
|
|
case .gr: return "Greece"
|
|
|
|
case .gt: return "Guatemala"
|
|
|
|
case .hn: return "Honduras"
|
|
|
|
case .hk: return "Hong Kong"
|
|
|
|
case .hu: return "Hungary"
|
|
|
|
case .is: return "Iceland"
|
|
|
|
case .in: return "India"
|
|
|
|
case .id: return "Indonesia"
|
|
|
|
case .iq: return "Iraq"
|
|
|
|
case .ie: return "Ireland"
|
|
|
|
case .il: return "Israel"
|
|
|
|
case .it: return "Italy"
|
|
|
|
case .jm: return "Jamaica"
|
|
|
|
case .jp: return "Japan"
|
|
|
|
case .jo: return "Jordan"
|
|
|
|
case .kz: return "Kazakhstan"
|
|
|
|
case .ke: return "Kenya"
|
|
|
|
case .kr: return "Korea (Republic of)"
|
|
|
|
case .kw: return "Kuwait"
|
|
|
|
case .lv: return "Latvia"
|
|
|
|
case .lb: return "Lebanon"
|
|
|
|
case .ly: return "Libya"
|
|
|
|
case .li: return "Liechtenstein"
|
|
|
|
case .lt: return "Lithuania"
|
|
|
|
case .lu: return "Luxembourg"
|
|
|
|
case .mk: return "Macedonia (the former Yugoslav Republic of)"
|
|
|
|
case .my: return "Malaysia"
|
|
|
|
case .mt: return "Malta"
|
|
|
|
case .mx: return "Mexico"
|
|
|
|
case .me: return "Montenegro"
|
|
|
|
case .ma: return "Morocco"
|
|
|
|
case .np: return "Nepal"
|
|
|
|
case .nl: return "Netherlands"
|
|
|
|
case .nz: return "New Zealand"
|
|
|
|
case .ni: return "Nicaragua"
|
|
|
|
case .ng: return "Nigeria"
|
|
|
|
case .no: return "Norway"
|
|
|
|
case .om: return "Oman"
|
|
|
|
case .pk: return "Pakistan"
|
|
|
|
case .pa: return "Panama"
|
|
|
|
case .pg: return "Papua New Guinea"
|
|
|
|
case .py: return "Paraguay"
|
|
|
|
case .pe: return "Peru"
|
|
|
|
case .ph: return "Philippines"
|
|
|
|
case .pl: return "Poland"
|
|
|
|
case .pt: return "Portugal"
|
|
|
|
case .pr: return "Puerto Rico"
|
|
|
|
case .qa: return "Qatar"
|
|
|
|
case .ro: return "Romania"
|
|
|
|
case .ru: return "Russian Federation"
|
|
|
|
case .sa: return "Saudi Arabia"
|
|
|
|
case .sn: return "Senegal"
|
|
|
|
case .rs: return "Serbia"
|
|
|
|
case .sg: return "Singapore"
|
|
|
|
case .sk: return "Slovakia"
|
|
|
|
case .si: return "Slovenia"
|
|
|
|
case .za: return "South Africa"
|
|
|
|
case .es: return "Spain"
|
|
|
|
case .lk: return "Sri Lanka"
|
|
|
|
case .se: return "Sweden"
|
|
|
|
case .ch: return "Switzerland"
|
2023-07-19 20:57:03 +05:30
|
|
|
case .tw: return "Taiwan"
|
2021-06-17 15:32:39 +05:30
|
|
|
case .tz: return "Tanzania, United Republic of"
|
|
|
|
case .th: return "Thailand"
|
|
|
|
case .tn: return "Tunisia"
|
|
|
|
case .tr: return "Turkey"
|
|
|
|
case .ug: return "Uganda"
|
|
|
|
case .ua: return "Ukraine"
|
|
|
|
case .ae: return "United Arab Emirates"
|
|
|
|
case .gb: return "United Kingdom of Great Britain and Northern Ireland"
|
|
|
|
case .us: return "United States of America"
|
|
|
|
case .uy: return "Uruguay"
|
|
|
|
case .ve: return "Venezuela (Bolivarian Republic of)"
|
|
|
|
case .vn: return "Viet Nam"
|
|
|
|
case .vi: return "Virgin Islands (U.S.)"
|
|
|
|
case .ye: return "Yemen"
|
|
|
|
case .zw: return "Zimbabwe"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-22 18:38:33 +05:30
|
|
|
// swiftlint:enable switch_case_on_newline
|
|
|
|
|
2021-06-17 15:32:39 +05:30
|
|
|
var flag: String {
|
|
|
|
let unicodeScalars = rawValue
|
|
|
|
.unicodeScalars
|
|
|
|
.map { $0.value + 0x1F1E6 - 65 }
|
|
|
|
.compactMap(UnicodeScalar.init)
|
|
|
|
var result = ""
|
|
|
|
result.unicodeScalars.append(contentsOf: unicodeScalars)
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2021-06-18 04:13:29 +05:30
|
|
|
static func search(_ query: String) -> [Country] {
|
|
|
|
if let country = searchByCode(query) {
|
|
|
|
return [country]
|
|
|
|
}
|
|
|
|
|
|
|
|
let countries = filteredCountries { stringFolding($0) == stringFolding(query) }
|
|
|
|
|
|
|
|
return countries.isEmpty ? searchByPartialName(query) : countries
|
|
|
|
}
|
2021-06-17 15:32:39 +05:30
|
|
|
|
2021-06-18 04:13:29 +05:30
|
|
|
static func searchByCode(_ code: String) -> Country? {
|
|
|
|
Country(rawValue: code.uppercased())
|
2021-06-17 15:32:39 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
static func searchByPartialName(_ name: String) -> [Country] {
|
2021-08-01 03:40:56 +05:30
|
|
|
guard !name.isEmpty else {
|
2021-06-17 15:32:39 +05:30
|
|
|
return []
|
|
|
|
}
|
|
|
|
|
2021-08-01 03:40:56 +05:30
|
|
|
return filteredCountries { stringFolding($0).contains(stringFolding(name)) }
|
2021-06-17 15:32:39 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
private static func stringFolding(_ string: String) -> String {
|
|
|
|
string.folding(options: [.diacriticInsensitive, .caseInsensitive], locale: .current)
|
|
|
|
}
|
|
|
|
|
|
|
|
private static func filteredCountries(_ predicate: (String) -> Bool) -> [Country] {
|
2021-06-18 04:13:29 +05:30
|
|
|
Country.allCases
|
2024-08-18 18:16:51 +05:30
|
|
|
.map(\.name)
|
2021-06-17 15:32:39 +05:30
|
|
|
.filter(predicate)
|
|
|
|
.compactMap { string in Country.allCases.first { $0.name == string } }
|
|
|
|
}
|
|
|
|
}
|