addressing 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/README.md +1 -1
- data/data/country/af.json +1 -1
- data/data/country/ak.json +258 -0
- data/data/country/am.json +18 -18
- data/data/country/ba.json +258 -0
- data/data/country/bn-IN.json +3 -3
- data/data/country/bn.json +3 -3
- data/data/country/bs.json +1 -0
- data/data/country/ca.json +9 -9
- data/data/country/cv.json +258 -0
- data/data/country/cy.json +1 -1
- data/data/country/en-AU.json +16 -16
- data/data/country/en-LT.json +258 -0
- data/data/country/en-LV.json +258 -0
- data/data/country/en-UA.json +258 -0
- data/data/country/fil.json +1 -1
- data/data/country/fr-CA.json +1 -1
- data/data/country/ga.json +17 -17
- data/data/country/gd.json +2 -2
- data/data/country/gl.json +20 -20
- data/data/country/gu.json +12 -12
- data/data/country/hr.json +17 -17
- data/data/country/hy.json +2 -2
- data/data/country/ig.json +30 -30
- data/data/country/is.json +1 -1
- data/data/country/it.json +8 -8
- data/data/country/kk-Arab.json +258 -0
- data/data/country/kok.json +158 -158
- data/data/country/ky.json +3 -3
- data/data/country/lt.json +1 -1
- data/data/country/lv.json +9 -9
- data/data/country/mk.json +1 -1
- data/data/country/ml.json +1 -1
- data/data/country/mn.json +9 -9
- data/data/country/mr.json +1 -1
- data/data/country/or.json +14 -14
- data/data/country/pa.json +7 -7
- data/data/country/qu.json +258 -0
- data/data/country/rm.json +258 -0
- data/data/country/shn.json +258 -0
- data/data/country/sl.json +16 -16
- data/data/country/so.json +2 -2
- data/data/country/sr-Cyrl-BA.json +1 -1
- data/data/country/sr-Cyrl-ME.json +1 -1
- data/data/country/sr-Cyrl-XK.json +1 -1
- data/data/country/sr-Latn-BA.json +1 -1
- data/data/country/sr-Latn-ME.json +1 -1
- data/data/country/sr-Latn-XK.json +1 -1
- data/data/country/sr-Latn.json +1 -1
- data/data/country/sr.json +1 -1
- data/data/country/sw-CD.json +1 -1
- data/data/country/sw.json +1 -1
- data/data/country/ta.json +3 -3
- data/data/country/te.json +11 -11
- data/data/country/vi.json +1 -1
- data/data/country/yue-Hans.json +11 -11
- data/data/country/yue.json +10 -10
- data/data/subdivision/VN.json +38 -154
- data/lib/addressing/address.rb +66 -78
- data/lib/addressing/address_format.rb +19 -8
- data/lib/addressing/country.rb +62 -30
- data/lib/addressing/default_formatter.rb +33 -19
- data/lib/addressing/enum.rb +4 -5
- data/lib/addressing/exceptions.rb +29 -0
- data/lib/addressing/field_override.rb +6 -13
- data/lib/addressing/locale.rb +25 -12
- data/lib/addressing/model.rb +0 -6
- data/lib/addressing/postal_label_formatter.rb +1 -1
- data/lib/addressing/subdivision.rb +36 -22
- data/lib/addressing/version.rb +1 -1
- data/lib/addressing.rb +1 -8
- metadata +17 -6
- /data/data/country/{en-ID.json → en-EE.json} +0 -0
- /data/data/country/{en-MV.json → en-GE.json} +0 -0
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Addressing
|
|
4
|
+
# Provides address format information for countries.
|
|
5
|
+
#
|
|
6
|
+
# Address formats define which fields are used, their order, requirements,
|
|
7
|
+
# and formatting rules for postal addresses in different countries.
|
|
8
|
+
#
|
|
9
|
+
# @example Get address format for Brazil
|
|
10
|
+
# format = Addressing::AddressFormat.get('BR')
|
|
11
|
+
# format.used_fields # => ["given_name", "family_name", ...]
|
|
12
|
+
# format.required_fields # => ["address_line1", "locality", ...]
|
|
4
13
|
class AddressFormat
|
|
5
14
|
class << self
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
15
|
+
# Gets the address format for the provided country code.
|
|
16
|
+
#
|
|
17
|
+
# @param country_code [String] ISO 3166-1 alpha-2 country code
|
|
18
|
+
# @return [AddressFormat] Address format instance
|
|
9
19
|
def get(country_code)
|
|
10
20
|
country_code = country_code.upcase
|
|
21
|
+
@address_formats ||= {}
|
|
11
22
|
|
|
12
|
-
unless
|
|
23
|
+
unless @address_formats.key?(country_code)
|
|
13
24
|
definition = process_definition(definitions[country_code] || {country_code: country_code})
|
|
14
|
-
|
|
25
|
+
@address_formats[country_code] = new(definition)
|
|
15
26
|
end
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
@address_formats[country_code]
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
def all
|
|
@@ -27,7 +38,7 @@ module Addressing
|
|
|
27
38
|
private
|
|
28
39
|
|
|
29
40
|
def definitions
|
|
30
|
-
|
|
41
|
+
@definitions ||= Marshal.load(File.read(File.expand_path("../../../data/address_formats.dump", __FILE__).to_s))
|
|
31
42
|
end
|
|
32
43
|
|
|
33
44
|
def process_definition(definition)
|
|
@@ -42,7 +53,7 @@ module Addressing
|
|
|
42
53
|
|
|
43
54
|
def generic_definition
|
|
44
55
|
{
|
|
45
|
-
format: "%given_name %family_name\n%organization\n%address_line1\n%address_line2\n
|
|
56
|
+
format: "%given_name %family_name\n%organization\n%address_line1\n%address_line2\n%address_line3\n%locality",
|
|
46
57
|
required_fields: [
|
|
47
58
|
"address_line1", "locality"
|
|
48
59
|
],
|
data/lib/addressing/country.rb
CHANGED
|
@@ -1,34 +1,55 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Addressing
|
|
4
|
+
# Provides country information including names, codes, currency, and timezones.
|
|
5
|
+
#
|
|
6
|
+
# Country names are available in over 250 locales powered by CLDR data.
|
|
7
|
+
#
|
|
8
|
+
# @example Get a country by code
|
|
9
|
+
# brazil = Addressing::Country.get('BR')
|
|
10
|
+
# brazil.name # => "Brazil"
|
|
11
|
+
# brazil.currency_code # => "BRL"
|
|
12
|
+
#
|
|
13
|
+
# @example Get all countries
|
|
14
|
+
# countries = Addressing::Country.all('fr-FR')
|
|
15
|
+
#
|
|
16
|
+
# @example Get a simple list of countries
|
|
17
|
+
# list = Addressing::Country.list('en')
|
|
4
18
|
class Country
|
|
5
19
|
class << self
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"es-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
20
|
+
AVAILABLE_LOCALES = [
|
|
21
|
+
"af", "ak", "am", "ar", "ar-LY", "ar-SA", "as", "az", "ba", "be", "bg",
|
|
22
|
+
"bn", "bn-IN", "bs", "ca", "chr", "cs", "cv", "cy", "da", "de",
|
|
23
|
+
"de-AT", "de-CH", "dsb", "el", "el-polyton", "en", "en-001", "en-AU",
|
|
24
|
+
"en-CA", "en-EE", "en-GE", "en-LT", "en-LV", "en-UA", "es", "es-419",
|
|
25
|
+
"es-AR", "es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-GT",
|
|
26
|
+
"es-HN", "es-MX", "es-NI", "es-PA", "es-PE", "es-PR", "es-PY", "es-SV",
|
|
27
|
+
"es-US", "es-VE", "et", "eu", "fa", "fa-AF", "fi", "fil", "fr",
|
|
28
|
+
"fr-BE", "fr-CA", "ga", "gd", "gl", "gu", "he", "hi", "hi-Latn", "hr",
|
|
29
|
+
"hsb", "hu", "hy", "id", "ig", "is", "it", "ja", "ka", "kk", "kk-Arab",
|
|
30
|
+
"km", "ko", "ko-KP", "kok", "ky", "lo", "lt", "lv", "mk", "ml", "mn",
|
|
31
|
+
"mr", "ms", "my", "ne", "nl", "nn", "no", "or", "pa", "pl", "ps",
|
|
32
|
+
"ps-PK", "pt", "pt-PT", "qu", "rm", "ro", "ro-MD", "ru", "ru-UA",
|
|
33
|
+
"shn", "si", "sk", "sl", "so", "sq", "sr", "sr-Cyrl-BA", "sr-Cyrl-ME",
|
|
34
|
+
"sr-Cyrl-XK", "sr-Latn", "sr-Latn-BA", "sr-Latn-ME", "sr-Latn-XK",
|
|
35
|
+
"sv", "sw", "sw-CD", "sw-KE", "ta", "te", "th", "tk", "tr", "uk", "ur",
|
|
36
|
+
"ur-IN", "uz", "vi", "yue", "yue-Hans", "zh", "zh-Hant", "zh-Hant-HK",
|
|
37
|
+
"zu"
|
|
24
38
|
]
|
|
25
39
|
|
|
40
|
+
# Gets a Country instance for the provided country code.
|
|
41
|
+
#
|
|
42
|
+
# @param country_code [String] ISO 3166-1 alpha-2 country code
|
|
43
|
+
# @param locale [String] Locale for the country name (default: "en")
|
|
44
|
+
# @param fallback_locale [String] Fallback locale if requested locale is unavailable
|
|
45
|
+
# @return [Country] Country instance
|
|
46
|
+
# @raise [UnknownCountryError] if the country code is not recognized
|
|
26
47
|
def get(country_code, locale = "en", fallback_locale = "en")
|
|
27
48
|
country_code = country_code.upcase
|
|
28
49
|
|
|
29
|
-
raise UnknownCountryError
|
|
50
|
+
raise UnknownCountryError.new(country_code) unless base_definitions.key?(country_code)
|
|
30
51
|
|
|
31
|
-
locale = Locale.resolve(
|
|
52
|
+
locale = Locale.resolve(AVAILABLE_LOCALES, locale, fallback_locale)
|
|
32
53
|
definitions = load_definitions(locale)
|
|
33
54
|
|
|
34
55
|
new(
|
|
@@ -41,8 +62,13 @@ module Addressing
|
|
|
41
62
|
)
|
|
42
63
|
end
|
|
43
64
|
|
|
65
|
+
# Gets all Country instances.
|
|
66
|
+
#
|
|
67
|
+
# @param locale [String] Locale for country names (default: "en")
|
|
68
|
+
# @param fallback_locale [String] Fallback locale if requested locale is unavailable
|
|
69
|
+
# @return [Hash<String, Country>] Hash of country code => Country instance
|
|
44
70
|
def all(locale = "en", fallback_locale = "en")
|
|
45
|
-
locale = Locale.resolve(
|
|
71
|
+
locale = Locale.resolve(AVAILABLE_LOCALES, locale, fallback_locale)
|
|
46
72
|
definitions = load_definitions(locale)
|
|
47
73
|
|
|
48
74
|
definitions.map do |country_code, country_name|
|
|
@@ -59,8 +85,13 @@ module Addressing
|
|
|
59
85
|
end.to_h
|
|
60
86
|
end
|
|
61
87
|
|
|
88
|
+
# Gets a list of country codes and names.
|
|
89
|
+
#
|
|
90
|
+
# @param locale [String] Locale for country names (default: "en")
|
|
91
|
+
# @param fallback_locale [String] Fallback locale if requested locale is unavailable
|
|
92
|
+
# @return [Hash<String, String>] Hash of country code => country name
|
|
62
93
|
def list(locale = "en", fallback_locale = "en")
|
|
63
|
-
locale = Locale.resolve(
|
|
94
|
+
locale = Locale.resolve(AVAILABLE_LOCALES, locale, fallback_locale)
|
|
64
95
|
definitions = load_definitions(locale)
|
|
65
96
|
|
|
66
97
|
definitions.map do |country_code, country_name|
|
|
@@ -72,19 +103,20 @@ module Addressing
|
|
|
72
103
|
|
|
73
104
|
# Loads the country definitions for the provided locale.
|
|
74
105
|
def load_definitions(locale)
|
|
75
|
-
|
|
106
|
+
@definitions ||= {}
|
|
107
|
+
unless @definitions.key?(locale)
|
|
76
108
|
filename = File.join(File.expand_path("../../../data/country", __FILE__).to_s, "#{locale}.json")
|
|
77
|
-
|
|
109
|
+
@definitions[locale] = JSON.parse(File.read(filename))
|
|
78
110
|
end
|
|
79
111
|
|
|
80
|
-
|
|
112
|
+
@definitions[locale]
|
|
81
113
|
end
|
|
82
114
|
|
|
83
115
|
# Gets the base country definitions.
|
|
84
116
|
#
|
|
85
117
|
# Contains data common to all locales: three letter code, numeric code.
|
|
86
118
|
def base_definitions
|
|
87
|
-
|
|
119
|
+
@base_definitions ||= {
|
|
88
120
|
"AC" => ["ASC", nil, "SHP"],
|
|
89
121
|
"AD" => ["AND", "020", "EUR"],
|
|
90
122
|
"AE" => ["ARE", "784", "AED"],
|
|
@@ -107,7 +139,7 @@ module Addressing
|
|
|
107
139
|
"BD" => ["BGD", "050", "BDT"],
|
|
108
140
|
"BE" => ["BEL", "056", "EUR"],
|
|
109
141
|
"BF" => ["BFA", "854", "XOF"],
|
|
110
|
-
"BG" => ["BGR", "100", "
|
|
142
|
+
"BG" => ["BGR", "100", "EUR"],
|
|
111
143
|
"BH" => ["BHR", "048", "BHD"],
|
|
112
144
|
"BI" => ["BDI", "108", "BIF"],
|
|
113
145
|
"BJ" => ["BEN", "204", "XOF"],
|
|
@@ -234,7 +266,7 @@ module Addressing
|
|
|
234
266
|
"MG" => ["MDG", "450", "MGA"],
|
|
235
267
|
"MH" => ["MHL", "584", "USD"],
|
|
236
268
|
"MK" => ["MKD", "807", "MKD"],
|
|
237
|
-
"ML" => ["MLI", "466",
|
|
269
|
+
"ML" => ["MLI", "466", nil],
|
|
238
270
|
"MM" => ["MMR", "104", "MMK"],
|
|
239
271
|
"MN" => ["MNG", "496", "MNT"],
|
|
240
272
|
"MO" => ["MAC", "446", "MOP"],
|
|
@@ -272,7 +304,7 @@ module Addressing
|
|
|
272
304
|
"PM" => ["SPM", "666", "EUR"],
|
|
273
305
|
"PN" => ["PCN", "612", "NZD"],
|
|
274
306
|
"PR" => ["PRI", "630", "USD"],
|
|
275
|
-
"PS" => ["PSE", "275", "
|
|
307
|
+
"PS" => ["PSE", "275", "ILS"],
|
|
276
308
|
"PT" => ["PRT", "620", "EUR"],
|
|
277
309
|
"PW" => ["PLW", "585", "USD"],
|
|
278
310
|
"PY" => ["PRY", "600", "PYG"],
|
|
@@ -340,7 +372,7 @@ module Addressing
|
|
|
340
372
|
"YT" => ["MYT", "175", "EUR"],
|
|
341
373
|
"ZA" => ["ZAF", "710", "ZAR"],
|
|
342
374
|
"ZM" => ["ZMB", "894", "ZMW"],
|
|
343
|
-
"ZW" => ["ZWE", "716", "
|
|
375
|
+
"ZW" => ["ZWE", "716", "ZWG"]
|
|
344
376
|
}
|
|
345
377
|
end
|
|
346
378
|
end
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module Addressing
|
|
4
4
|
class DefaultFormatter
|
|
5
|
+
DEFAULT_LOCALE = "en"
|
|
6
|
+
FORMAT_PLACEHOLDER_PATTERN = /%[a-z1-9_]+/
|
|
7
|
+
LEADING_TRAILING_PUNCTUATION_PATTERN = /\A[ \-,]+|[ \-,]+\z/
|
|
8
|
+
MULTIPLE_SPACES_PATTERN = /\s\s+/
|
|
9
|
+
|
|
5
10
|
DEFAULT_OPTIONS = {
|
|
6
|
-
locale:
|
|
11
|
+
locale: DEFAULT_LOCALE,
|
|
7
12
|
html: true,
|
|
8
13
|
html_tag: "p",
|
|
9
14
|
html_attributes: {translate: "no"}
|
|
@@ -13,6 +18,7 @@ module Addressing
|
|
|
13
18
|
assert_options(default_options)
|
|
14
19
|
|
|
15
20
|
@default_options = self.class::DEFAULT_OPTIONS.merge(default_options)
|
|
21
|
+
@country_list_cache = {}
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
def format(address, options = {})
|
|
@@ -33,7 +39,7 @@ module Addressing
|
|
|
33
39
|
view = render_view(view)
|
|
34
40
|
|
|
35
41
|
replacements = view.map { |key, element| ["%#{key}", element] }.to_h
|
|
36
|
-
output = format_string.gsub(
|
|
42
|
+
output = format_string.gsub(FORMAT_PLACEHOLDER_PATTERN) { |m| replacements[m] }
|
|
37
43
|
output = clean_output(output)
|
|
38
44
|
|
|
39
45
|
if options[:html]
|
|
@@ -49,7 +55,7 @@ module Addressing
|
|
|
49
55
|
|
|
50
56
|
# Builds the view for the given address.
|
|
51
57
|
def build_view(address, address_format, options)
|
|
52
|
-
countries =
|
|
58
|
+
countries = country_list(options[:locale])
|
|
53
59
|
values = values(address, address_format).merge({"country" => countries.key?(address.country_code) ? countries[address.country_code] : address.country_code})
|
|
54
60
|
used_fields = address_format.used_fields + ["country"]
|
|
55
61
|
|
|
@@ -58,6 +64,11 @@ module Addressing
|
|
|
58
64
|
end.to_h
|
|
59
65
|
end
|
|
60
66
|
|
|
67
|
+
# Gets the country list for a locale, with caching.
|
|
68
|
+
def country_list(locale)
|
|
69
|
+
@country_list_cache[locale] ||= Country.list(locale)
|
|
70
|
+
end
|
|
71
|
+
|
|
61
72
|
# Renders the given view.
|
|
62
73
|
def render_view(view)
|
|
63
74
|
view.map do |key, element|
|
|
@@ -90,27 +101,34 @@ module Addressing
|
|
|
90
101
|
|
|
91
102
|
# Removes empty lines, leading punctuation, excess whitespace.
|
|
92
103
|
def clean_output(output)
|
|
93
|
-
output.split("\n").map { |line| line.gsub(
|
|
104
|
+
output.split("\n").map { |line| line.gsub(LEADING_TRAILING_PUNCTUATION_PATTERN, "").strip.gsub(MULTIPLE_SPACES_PATTERN, " ") }.reject(&:empty?).join("\n")
|
|
94
105
|
end
|
|
95
106
|
|
|
96
107
|
# Gets the address values used to build the view.
|
|
97
108
|
def values(address, address_format)
|
|
98
|
-
values =
|
|
109
|
+
values = extract_address_values(address)
|
|
110
|
+
resolve_subdivision_values(values, address, address_format)
|
|
111
|
+
values
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Extracts all address field values.
|
|
115
|
+
def extract_address_values(address)
|
|
116
|
+
AddressField.all.map { |_, field| [field, address.send(field)] }.to_h
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Resolves subdivision values to their display codes.
|
|
120
|
+
def resolve_subdivision_values(values, address, address_format)
|
|
99
121
|
subdivision_fields = address_format.used_subdivision_fields
|
|
100
122
|
|
|
101
123
|
# Replace the subdivision values with the names of any predefined ones.
|
|
102
124
|
subdivision_fields.each_with_index.inject([{}, []]) do |(original_values, parents), (field, index)|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
break
|
|
106
|
-
end
|
|
125
|
+
# This level is empty, so there can be no sublevels.
|
|
126
|
+
break if values[field].nil?
|
|
107
127
|
|
|
108
128
|
parents << ((index > 0) ? original_values[subdivision_fields[index - 1]] : address.country_code)
|
|
109
129
|
|
|
110
130
|
subdivision = Subdivision.get(values[field], parents)
|
|
111
|
-
if subdivision.nil?
|
|
112
|
-
break
|
|
113
|
-
end
|
|
131
|
+
break if subdivision.nil?
|
|
114
132
|
|
|
115
133
|
# Remember the original value so that it can be used for parents.
|
|
116
134
|
original_values[field] = values[field]
|
|
@@ -119,15 +137,11 @@ module Addressing
|
|
|
119
137
|
use_local_name = Locale.match_candidates(address.locale, subdivision.locale)
|
|
120
138
|
values[field] = use_local_name ? subdivision.local_code : subdivision.code
|
|
121
139
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
break
|
|
125
|
-
end
|
|
140
|
+
# The current subdivision has no children, stop.
|
|
141
|
+
break unless subdivision.children?
|
|
126
142
|
|
|
127
143
|
[original_values, parents]
|
|
128
144
|
end
|
|
129
|
-
|
|
130
|
-
values
|
|
131
145
|
end
|
|
132
146
|
|
|
133
147
|
private
|
|
@@ -142,7 +156,7 @@ module Addressing
|
|
|
142
156
|
end
|
|
143
157
|
end
|
|
144
158
|
|
|
145
|
-
if options.key?(:html) && !
|
|
159
|
+
if options.key?(:html) && ![true, false].include?(options[:html])
|
|
146
160
|
raise ArgumentError, "The option `html` must be a boolean."
|
|
147
161
|
end
|
|
148
162
|
|
data/lib/addressing/enum.rb
CHANGED
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
module Addressing
|
|
4
4
|
class Enum
|
|
5
5
|
class << self
|
|
6
|
-
@@values = {}
|
|
7
|
-
|
|
8
6
|
# Gets all available values.
|
|
9
7
|
def all
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
@values ||= {}
|
|
9
|
+
if !@values.key?(name)
|
|
10
|
+
@values[name] = constants.map { |constant| [constant, const_get(constant)] }.to_h
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
@values[name]
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
# Gets the key of the provided value.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Addressing
|
|
4
|
+
# Base error class for all Addressing errors
|
|
5
|
+
class Error < StandardError; end
|
|
6
|
+
|
|
7
|
+
# Raised when an unknown country code is provided
|
|
8
|
+
class UnknownCountryError < Error
|
|
9
|
+
def initialize(country_code)
|
|
10
|
+
super("Unknown country code: #{country_code}")
|
|
11
|
+
@country_code = country_code
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :country_code
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Raised when an unknown locale is provided
|
|
18
|
+
class UnknownLocaleError < Error
|
|
19
|
+
def initialize(locale)
|
|
20
|
+
super("Unknown locale: #{locale}")
|
|
21
|
+
@locale = locale
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
attr_reader :locale
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Raised when an invalid argument is provided
|
|
28
|
+
class InvalidArgumentError < Error; end
|
|
29
|
+
end
|
|
@@ -14,20 +14,13 @@ module Addressing
|
|
|
14
14
|
AddressField.assert_all_exist(definition.keys)
|
|
15
15
|
FieldOverride.assert_all_exist(definition.values)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
# Group fields by their override type
|
|
18
|
+
grouped = definition.group_by { |_field, override| override }
|
|
19
|
+
.transform_values { |pairs| pairs.map(&:first) }
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@hidden_fields << field
|
|
25
|
-
when FieldOverride::OPTIONAL
|
|
26
|
-
@optional_fields << field
|
|
27
|
-
when FieldOverride::REQUIRED
|
|
28
|
-
@required_fields << field
|
|
29
|
-
end
|
|
30
|
-
end
|
|
21
|
+
@hidden_fields = grouped[FieldOverride::HIDDEN] || []
|
|
22
|
+
@optional_fields = grouped[FieldOverride::OPTIONAL] || []
|
|
23
|
+
@required_fields = grouped[FieldOverride::REQUIRED] || []
|
|
31
24
|
end
|
|
32
25
|
end
|
|
33
26
|
end
|
data/lib/addressing/locale.rb
CHANGED
|
@@ -52,36 +52,49 @@ module Addressing
|
|
|
52
52
|
"en-150" => "en-001",
|
|
53
53
|
"en-AG" => "en-001",
|
|
54
54
|
"en-AI" => "en-001",
|
|
55
|
+
"en-AT" => "en-150",
|
|
55
56
|
"en-AU" => "en-001",
|
|
56
57
|
"en-BB" => "en-001",
|
|
58
|
+
"en-BE" => "en-150",
|
|
57
59
|
"en-BM" => "en-001",
|
|
58
60
|
"en-BS" => "en-001",
|
|
59
61
|
"en-BW" => "en-001",
|
|
60
62
|
"en-BZ" => "en-001",
|
|
61
63
|
"en-CC" => "en-001",
|
|
64
|
+
"en-CH" => "en-150",
|
|
62
65
|
"en-CK" => "en-001",
|
|
63
66
|
"en-CM" => "en-001",
|
|
64
67
|
"en-CX" => "en-001",
|
|
65
68
|
"en-CY" => "en-001",
|
|
69
|
+
"en-CZ" => "en-150",
|
|
70
|
+
"en-DE" => "en-150",
|
|
66
71
|
"en-DG" => "en-001",
|
|
72
|
+
"en-DK" => "en-150",
|
|
67
73
|
"en-DM" => "en-001",
|
|
68
74
|
"en-ER" => "en-001",
|
|
75
|
+
"en-ES" => "en-150",
|
|
76
|
+
"en-FI" => "en-150",
|
|
69
77
|
"en-FJ" => "en-001",
|
|
70
78
|
"en-FK" => "en-001",
|
|
71
79
|
"en-FM" => "en-001",
|
|
80
|
+
"en-FR" => "en-150",
|
|
72
81
|
"en-GB" => "en-001",
|
|
73
82
|
"en-GD" => "en-001",
|
|
74
83
|
"en-GG" => "en-001",
|
|
75
84
|
"en-GH" => "en-001",
|
|
76
85
|
"en-GI" => "en-001",
|
|
77
86
|
"en-GM" => "en-001",
|
|
87
|
+
"en-GS" => "en-001",
|
|
78
88
|
"en-GY" => "en-001",
|
|
79
89
|
"en-HK" => "en-001",
|
|
90
|
+
"en-HU" => "en-150",
|
|
91
|
+
"en-ID" => "en-001",
|
|
80
92
|
"en-IE" => "en-001",
|
|
81
93
|
"en-IL" => "en-001",
|
|
82
94
|
"en-IM" => "en-001",
|
|
83
95
|
"en-IN" => "en-001",
|
|
84
96
|
"en-IO" => "en-001",
|
|
97
|
+
"en-IT" => "en-150",
|
|
85
98
|
"en-JE" => "en-001",
|
|
86
99
|
"en-JM" => "en-001",
|
|
87
100
|
"en-KE" => "en-001",
|
|
@@ -96,24 +109,33 @@ module Addressing
|
|
|
96
109
|
"en-MS" => "en-001",
|
|
97
110
|
"en-MT" => "en-001",
|
|
98
111
|
"en-MU" => "en-001",
|
|
112
|
+
"en-MV" => "en-001",
|
|
99
113
|
"en-MW" => "en-001",
|
|
100
114
|
"en-MY" => "en-001",
|
|
101
115
|
"en-NA" => "en-001",
|
|
102
116
|
"en-NF" => "en-001",
|
|
103
117
|
"en-NG" => "en-001",
|
|
118
|
+
"en-NL" => "en-150",
|
|
119
|
+
"en-NO" => "en-150",
|
|
104
120
|
"en-NR" => "en-001",
|
|
105
121
|
"en-NU" => "en-001",
|
|
106
122
|
"en-NZ" => "en-001",
|
|
107
123
|
"en-PG" => "en-001",
|
|
108
124
|
"en-PK" => "en-001",
|
|
125
|
+
"en-PL" => "en-150",
|
|
109
126
|
"en-PN" => "en-001",
|
|
127
|
+
"en-PT" => "en-150",
|
|
110
128
|
"en-PW" => "en-001",
|
|
129
|
+
"en-RO" => "en-150",
|
|
111
130
|
"en-RW" => "en-001",
|
|
112
131
|
"en-SB" => "en-001",
|
|
113
132
|
"en-SC" => "en-001",
|
|
114
133
|
"en-SD" => "en-001",
|
|
134
|
+
"en-SE" => "en-150",
|
|
115
135
|
"en-SG" => "en-001",
|
|
116
136
|
"en-SH" => "en-001",
|
|
137
|
+
"en-SI" => "en-150",
|
|
138
|
+
"en-SK" => "en-150",
|
|
117
139
|
"en-SL" => "en-001",
|
|
118
140
|
"en-SS" => "en-001",
|
|
119
141
|
"en-SX" => "en-001",
|
|
@@ -132,15 +154,6 @@ module Addressing
|
|
|
132
154
|
"en-ZA" => "en-001",
|
|
133
155
|
"en-ZM" => "en-001",
|
|
134
156
|
"en-ZW" => "en-001",
|
|
135
|
-
"en-AT" => "en-150",
|
|
136
|
-
"en-BE" => "en-150",
|
|
137
|
-
"en-CH" => "en-150",
|
|
138
|
-
"en-DE" => "en-150",
|
|
139
|
-
"en-DK" => "en-150",
|
|
140
|
-
"en-FI" => "en-150",
|
|
141
|
-
"en-NL" => "en-150",
|
|
142
|
-
"en-SE" => "en-150",
|
|
143
|
-
"en-SI" => "en-150",
|
|
144
157
|
"es-AR" => "es-419",
|
|
145
158
|
"es-BO" => "es-419",
|
|
146
159
|
"es-BR" => "es-419",
|
|
@@ -163,12 +176,13 @@ module Addressing
|
|
|
163
176
|
"es-US" => "es-419",
|
|
164
177
|
"es-UY" => "es-419",
|
|
165
178
|
"es-VE" => "es-419",
|
|
179
|
+
"hi-Latn" => "und",
|
|
180
|
+
"ht" => "fr-HT",
|
|
166
181
|
"nb" => "no",
|
|
167
182
|
"nn" => "no",
|
|
168
183
|
"pt-AO" => "pt-PT",
|
|
169
184
|
"pt-CH" => "pt-PT",
|
|
170
185
|
"pt-CV" => "pt-PT",
|
|
171
|
-
"pt-FR" => "pt-PT",
|
|
172
186
|
"pt-GQ" => "pt-PT",
|
|
173
187
|
"pt-GW" => "pt-PT",
|
|
174
188
|
"pt-LU" => "pt-PT",
|
|
@@ -184,7 +198,6 @@ module Addressing
|
|
|
184
198
|
"byn-Latn" => "und",
|
|
185
199
|
"en-Dsrt" => "und",
|
|
186
200
|
"en-Shaw" => "und",
|
|
187
|
-
"hi-Latn" => "und",
|
|
188
201
|
"iu-Latn" => "und",
|
|
189
202
|
"kk-Arab" => "und",
|
|
190
203
|
"ks-Deva" => "und",
|
|
@@ -251,7 +264,7 @@ module Addressing
|
|
|
251
264
|
end
|
|
252
265
|
|
|
253
266
|
# No locale could be resolved, stop here.
|
|
254
|
-
raise UnknownLocaleError
|
|
267
|
+
raise UnknownLocaleError.new(locale) if resolved_locale.nil?
|
|
255
268
|
|
|
256
269
|
resolved_locale
|
|
257
270
|
end
|
data/lib/addressing/model.rb
CHANGED
|
@@ -20,12 +20,6 @@ module Addressing
|
|
|
20
20
|
return unless address.country_code.present?
|
|
21
21
|
|
|
22
22
|
address_format = AddressFormat.get(address.country_code)
|
|
23
|
-
address_format.used_fields
|
|
24
|
-
|
|
25
|
-
return unless address.country_code.present?
|
|
26
|
-
|
|
27
|
-
address_format = AddressFormat.get(address.country_code)
|
|
28
|
-
address_format.used_fields
|
|
29
23
|
|
|
30
24
|
# Validate the presence of required fields.
|
|
31
25
|
AddressFormatHelper.required_fields(address_format, field_overrides).each do |required_field|
|