addressing 2.0.1 → 2.1.0
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 +8 -0
- data/README.md +2 -1
- data/data/address_formats.dump +0 -0
- data/data/address_formats.json +64 -64
- data/data/subdivision/AE.json +1 -1
- data/data/subdivision/CA.json +6 -12
- data/data/subdivision/CO.json +1 -1
- data/data/subdivision/GB.json +675 -0
- data/data/subdivision/GT.json +71 -0
- data/data/subdivision/IT.json +13 -1
- data/data/subdivision/NG.json +1 -1
- data/data/subdivision/RU.json +4 -4
- data/data/subdivision/TH.json +7 -7
- data/data/subdivision/TR.json +1 -1
- data/data/subdivision/VE.json +4 -4
- data/data/subdivision/VN.json +1 -1
- data/lib/addressing/address_format.rb +38 -16
- data/lib/addressing/default_formatter.rb +40 -12
- data/lib/addressing/model.rb +9 -10
- data/lib/addressing/subdivision.rb +25 -7
- data/lib/addressing/version.rb +1 -1
- metadata +4 -2
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"country_code": "GT",
|
|
3
|
+
"subdivisions": {
|
|
4
|
+
"16": {
|
|
5
|
+
"name": "Alta Verapaz"
|
|
6
|
+
},
|
|
7
|
+
"15": {
|
|
8
|
+
"name": "Baja Verapaz"
|
|
9
|
+
},
|
|
10
|
+
"04": {
|
|
11
|
+
"name": "Chimaltenango"
|
|
12
|
+
},
|
|
13
|
+
"20": {
|
|
14
|
+
"name": "Chiquimula"
|
|
15
|
+
},
|
|
16
|
+
"02": {
|
|
17
|
+
"name": "El Progreso"
|
|
18
|
+
},
|
|
19
|
+
"05": {
|
|
20
|
+
"name": "Escuintla"
|
|
21
|
+
},
|
|
22
|
+
"01": {
|
|
23
|
+
"name": "Guatemala"
|
|
24
|
+
},
|
|
25
|
+
"13": {
|
|
26
|
+
"name": "Huehuetenango"
|
|
27
|
+
},
|
|
28
|
+
"18": {
|
|
29
|
+
"name": "Izabal"
|
|
30
|
+
},
|
|
31
|
+
"21": {
|
|
32
|
+
"name": "Jalapa"
|
|
33
|
+
},
|
|
34
|
+
"22": {
|
|
35
|
+
"name": "Jutiapa"
|
|
36
|
+
},
|
|
37
|
+
"17": {
|
|
38
|
+
"name": "Petén"
|
|
39
|
+
},
|
|
40
|
+
"09": {
|
|
41
|
+
"name": "Quetzaltenango"
|
|
42
|
+
},
|
|
43
|
+
"14": {
|
|
44
|
+
"name": "Quiché"
|
|
45
|
+
},
|
|
46
|
+
"11": {
|
|
47
|
+
"name": "Retalhuleu"
|
|
48
|
+
},
|
|
49
|
+
"03": {
|
|
50
|
+
"name": "Sacatepéquez"
|
|
51
|
+
},
|
|
52
|
+
"12": {
|
|
53
|
+
"name": "San Marcos"
|
|
54
|
+
},
|
|
55
|
+
"06": {
|
|
56
|
+
"name": "Santa Rosa"
|
|
57
|
+
},
|
|
58
|
+
"07": {
|
|
59
|
+
"name": "Sololá"
|
|
60
|
+
},
|
|
61
|
+
"10": {
|
|
62
|
+
"name": "Suchitepéquez"
|
|
63
|
+
},
|
|
64
|
+
"08": {
|
|
65
|
+
"name": "Totonicapán"
|
|
66
|
+
},
|
|
67
|
+
"19": {
|
|
68
|
+
"name": "Zacapa"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
data/data/subdivision/IT.json
CHANGED
|
@@ -149,6 +149,10 @@
|
|
|
149
149
|
"code": "FR",
|
|
150
150
|
"name": "Frosinone"
|
|
151
151
|
},
|
|
152
|
+
"OT": {
|
|
153
|
+
"code": "OT",
|
|
154
|
+
"name": "Gallura Nord-Est Sardegna"
|
|
155
|
+
},
|
|
152
156
|
"GE": {
|
|
153
157
|
"code": "GE",
|
|
154
158
|
"name": "Genova"
|
|
@@ -217,6 +221,10 @@
|
|
|
217
221
|
"code": "MT",
|
|
218
222
|
"name": "Matera"
|
|
219
223
|
},
|
|
224
|
+
"VS": {
|
|
225
|
+
"code": "VS",
|
|
226
|
+
"name": "Medio Campidano"
|
|
227
|
+
},
|
|
220
228
|
"ME": {
|
|
221
229
|
"code": "ME",
|
|
222
230
|
"name": "Messina"
|
|
@@ -245,6 +253,10 @@
|
|
|
245
253
|
"code": "NU",
|
|
246
254
|
"name": "Nuoro"
|
|
247
255
|
},
|
|
256
|
+
"OG": {
|
|
257
|
+
"code": "OG",
|
|
258
|
+
"name": "Ogliastra"
|
|
259
|
+
},
|
|
248
260
|
"OR": {
|
|
249
261
|
"code": "OR",
|
|
250
262
|
"name": "Oristano"
|
|
@@ -359,7 +371,7 @@
|
|
|
359
371
|
},
|
|
360
372
|
"SU": {
|
|
361
373
|
"code": "SU",
|
|
362
|
-
"name": "
|
|
374
|
+
"name": "Sulcis Iglesiente"
|
|
363
375
|
},
|
|
364
376
|
"TA": {
|
|
365
377
|
"code": "TA",
|
data/data/subdivision/NG.json
CHANGED
data/data/subdivision/RU.json
CHANGED
|
@@ -240,10 +240,6 @@
|
|
|
240
240
|
"name": "Tyva Republits",
|
|
241
241
|
"local_name": "Республика Тыва"
|
|
242
242
|
},
|
|
243
|
-
"UD": {
|
|
244
|
-
"name": "Udmurtskaja Respublika",
|
|
245
|
-
"local_name": "Республика Удмуртия"
|
|
246
|
-
},
|
|
247
243
|
"KK": {
|
|
248
244
|
"name": "Khakasiya Republits",
|
|
249
245
|
"local_name": "Республика Хакасия"
|
|
@@ -308,6 +304,10 @@
|
|
|
308
304
|
"name": "Tyumenskaya oblast'",
|
|
309
305
|
"local_name": "Тюменская область"
|
|
310
306
|
},
|
|
307
|
+
"UD": {
|
|
308
|
+
"name": "Udmurtskaja Respublika",
|
|
309
|
+
"local_name": "Удмуртская Республика"
|
|
310
|
+
},
|
|
311
311
|
"ULY": {
|
|
312
312
|
"name": "Ulyanovskaya oblast'",
|
|
313
313
|
"local_name": "Ульяновская область"
|
data/data/subdivision/TH.json
CHANGED
|
@@ -26,10 +26,6 @@
|
|
|
26
26
|
"name": "Khon Kaen",
|
|
27
27
|
"local_name": "ขอนแก่น"
|
|
28
28
|
},
|
|
29
|
-
"38": {
|
|
30
|
-
"name": "Bueng Kan",
|
|
31
|
-
"local_name": "จังหวัด บึงกาฬ"
|
|
32
|
-
},
|
|
33
29
|
"22": {
|
|
34
30
|
"name": "Chanthaburi",
|
|
35
31
|
"local_name": "จันทบุรี"
|
|
@@ -51,7 +47,7 @@
|
|
|
51
47
|
"local_name": "ชัยภูมิ"
|
|
52
48
|
},
|
|
53
49
|
"86": {
|
|
54
|
-
"name": "
|
|
50
|
+
"name": "Chumphon",
|
|
55
51
|
"local_name": "ชุมพร"
|
|
56
52
|
},
|
|
57
53
|
"57": {
|
|
@@ -110,6 +106,10 @@
|
|
|
110
106
|
"name": "Nan",
|
|
111
107
|
"local_name": "น่าน"
|
|
112
108
|
},
|
|
109
|
+
"38": {
|
|
110
|
+
"name": "Bueng Kan",
|
|
111
|
+
"local_name": "บึงกาฬ"
|
|
112
|
+
},
|
|
113
113
|
"31": {
|
|
114
114
|
"name": "Buri Ram",
|
|
115
115
|
"local_name": "บุรีรัมย์"
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"local_name": "พังงา"
|
|
144
144
|
},
|
|
145
145
|
"93": {
|
|
146
|
-
"name": "
|
|
146
|
+
"name": "Phatthalung",
|
|
147
147
|
"local_name": "พัทลุง"
|
|
148
148
|
},
|
|
149
149
|
"66": {
|
|
@@ -267,7 +267,7 @@
|
|
|
267
267
|
"local_name": "สุโขทัย"
|
|
268
268
|
},
|
|
269
269
|
"72": {
|
|
270
|
-
"name": "
|
|
270
|
+
"name": "Suphan Buri",
|
|
271
271
|
"local_name": "สุพรรณบุรี"
|
|
272
272
|
},
|
|
273
273
|
"84": {
|
data/data/subdivision/TR.json
CHANGED
data/data/subdivision/VE.json
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"name": "Dependencias Federales"
|
|
33
33
|
},
|
|
34
34
|
"A": {
|
|
35
|
-
"name": "Distrito
|
|
35
|
+
"name": "Distrito Capital"
|
|
36
36
|
},
|
|
37
37
|
"I": {
|
|
38
38
|
"name": "Falcón"
|
|
@@ -40,6 +40,9 @@
|
|
|
40
40
|
"J": {
|
|
41
41
|
"name": "Guárico"
|
|
42
42
|
},
|
|
43
|
+
"X": {
|
|
44
|
+
"name": "La Guaira"
|
|
45
|
+
},
|
|
43
46
|
"K": {
|
|
44
47
|
"name": "Lara"
|
|
45
48
|
},
|
|
@@ -67,9 +70,6 @@
|
|
|
67
70
|
"T": {
|
|
68
71
|
"name": "Trujillo"
|
|
69
72
|
},
|
|
70
|
-
"X": {
|
|
71
|
-
"name": "La Guaira"
|
|
72
|
-
},
|
|
73
73
|
"U": {
|
|
74
74
|
"name": "Yaracuy"
|
|
75
75
|
},
|
data/data/subdivision/VN.json
CHANGED
|
@@ -8,9 +8,17 @@ module Addressing
|
|
|
8
8
|
#
|
|
9
9
|
# @example Get address format for Brazil
|
|
10
10
|
# format = Addressing::AddressFormat.get('BR')
|
|
11
|
-
# format.used_fields
|
|
12
|
-
# format.required_fields
|
|
11
|
+
# format.used_fields # => ["given_name", "family_name", ...]
|
|
12
|
+
# format.required_fields # => ["address_line1", "locality", ...]
|
|
13
|
+
# format.subdivision_fields # => ["administrative_area", "locality"]
|
|
13
14
|
class AddressFormat
|
|
15
|
+
# The subdivision fields, ordered from the top level down.
|
|
16
|
+
SUBDIVISION_FIELDS = [
|
|
17
|
+
AddressField::ADMINISTRATIVE_AREA,
|
|
18
|
+
AddressField::LOCALITY,
|
|
19
|
+
AddressField::DEPENDENT_LOCALITY
|
|
20
|
+
].freeze
|
|
21
|
+
|
|
14
22
|
class << self
|
|
15
23
|
# Gets the address format for the provided country code.
|
|
16
24
|
#
|
|
@@ -63,13 +71,28 @@ module Addressing
|
|
|
63
71
|
administrative_area_type: "province",
|
|
64
72
|
locality_type: "city",
|
|
65
73
|
dependent_locality_type: "suburb",
|
|
66
|
-
postal_code_type: "postal"
|
|
67
|
-
subdivision_depth: 0
|
|
74
|
+
postal_code_type: "postal"
|
|
68
75
|
}
|
|
69
76
|
end
|
|
70
77
|
end
|
|
71
78
|
|
|
72
|
-
attr_reader :country_code, :locale, :format, :local_format, :required_fields, :uppercase_fields, :default_values, :administrative_area_type, :locality_type, :dependent_locality_type, :postal_code_type, :postal_code_pattern, :postal_code_prefix
|
|
79
|
+
attr_reader :country_code, :locale, :format, :local_format, :required_fields, :uppercase_fields, :default_values, :administrative_area_type, :locality_type, :dependent_locality_type, :postal_code_type, :postal_code_pattern, :postal_code_prefix
|
|
80
|
+
|
|
81
|
+
# The subdivision fields for which there is predefined subdivision data.
|
|
82
|
+
#
|
|
83
|
+
# This is more precise than #used_subdivision_fields, which returns all
|
|
84
|
+
# subdivision fields used by the format regardless of whether data exists.
|
|
85
|
+
#
|
|
86
|
+
# @return [Array<String>] e.g. ["administrative_area", "locality"]
|
|
87
|
+
attr_reader :subdivision_fields
|
|
88
|
+
|
|
89
|
+
# The number of subdivision fields with predefined data used by the format.
|
|
90
|
+
#
|
|
91
|
+
# @deprecated Use #subdivision_fields instead.
|
|
92
|
+
# @return [Integer]
|
|
93
|
+
def subdivision_depth
|
|
94
|
+
(subdivision_fields & used_subdivision_fields).size
|
|
95
|
+
end
|
|
73
96
|
|
|
74
97
|
def initialize(definition = {})
|
|
75
98
|
# Validate the presence of required properties.
|
|
@@ -87,13 +110,16 @@ module Addressing
|
|
|
87
110
|
uppercase_fields: [],
|
|
88
111
|
default_values: {},
|
|
89
112
|
postal_code_pattern: nil,
|
|
90
|
-
postal_code_prefix: nil
|
|
91
|
-
subdivision_depth: 0
|
|
113
|
+
postal_code_prefix: nil
|
|
92
114
|
}.merge(definition)
|
|
93
115
|
|
|
116
|
+
# Backwards compatibility: derive the subdivision fields from a depth.
|
|
117
|
+
definition[:subdivision_fields] ||= SUBDIVISION_FIELDS.first(definition[:subdivision_depth] || 0)
|
|
118
|
+
|
|
94
119
|
AddressField.assert_all_exist(definition[:required_fields])
|
|
95
120
|
AddressField.assert_all_exist(definition[:uppercase_fields])
|
|
96
121
|
AddressField.assert_all_exist(definition[:default_values].keys)
|
|
122
|
+
AddressField.assert_all_exist(definition[:subdivision_fields])
|
|
97
123
|
|
|
98
124
|
@country_code = definition[:country_code]
|
|
99
125
|
@locale = definition[:locale]
|
|
@@ -102,7 +128,7 @@ module Addressing
|
|
|
102
128
|
@required_fields = definition[:required_fields]
|
|
103
129
|
@uppercase_fields = definition[:uppercase_fields]
|
|
104
130
|
@default_values = definition[:default_values]
|
|
105
|
-
@
|
|
131
|
+
@subdivision_fields = definition[:subdivision_fields]
|
|
106
132
|
|
|
107
133
|
if used_fields.include?(AddressField::ADMINISTRATIVE_AREA)
|
|
108
134
|
if definition[:administrative_area_type]
|
|
@@ -144,15 +170,11 @@ module Addressing
|
|
|
144
170
|
end
|
|
145
171
|
|
|
146
172
|
# Gets the list of used subdivision fields.
|
|
173
|
+
#
|
|
174
|
+
# Note that a country might use a subdivision field without having
|
|
175
|
+
# predefined subdivisions for it, see #subdivision_fields.
|
|
147
176
|
def used_subdivision_fields
|
|
148
|
-
|
|
149
|
-
AddressField::ADMINISTRATIVE_AREA,
|
|
150
|
-
AddressField::LOCALITY,
|
|
151
|
-
AddressField::DEPENDENT_LOCALITY
|
|
152
|
-
]
|
|
153
|
-
|
|
154
|
-
# Remove fields not used by the format.
|
|
155
|
-
fields & used_fields
|
|
177
|
+
SUBDIVISION_FIELDS & used_fields
|
|
156
178
|
end
|
|
157
179
|
end
|
|
158
180
|
|
|
@@ -4,6 +4,7 @@ module Addressing
|
|
|
4
4
|
class DefaultFormatter
|
|
5
5
|
DEFAULT_LOCALE = "en"
|
|
6
6
|
FORMAT_PLACEHOLDER_PATTERN = /%[a-z1-9_]+/
|
|
7
|
+
FORMAT_SPLIT_PATTERN = /(#{FORMAT_PLACEHOLDER_PATTERN})/
|
|
7
8
|
LEADING_TRAILING_PUNCTUATION_PATTERN = /\A[ \-,]+|[ \-,]+\z/
|
|
8
9
|
MULTIPLE_SPACES_PATTERN = /\s\s+/
|
|
9
10
|
|
|
@@ -39,7 +40,7 @@ module Addressing
|
|
|
39
40
|
view = render_view(view)
|
|
40
41
|
|
|
41
42
|
replacements = view.map { |key, element| ["%#{key}", element] }.to_h
|
|
42
|
-
output = format_string
|
|
43
|
+
output = insert_values(format_string, replacements)
|
|
43
44
|
output = clean_output(output)
|
|
44
45
|
|
|
45
46
|
if options[:html]
|
|
@@ -99,6 +100,39 @@ module Addressing
|
|
|
99
100
|
end.join(" ")
|
|
100
101
|
end
|
|
101
102
|
|
|
103
|
+
# Inserts the rendered address fields into the format string.
|
|
104
|
+
#
|
|
105
|
+
# Empty fields need special handling. When one falls between two values,
|
|
106
|
+
# keep the separator before it and discard the one after it.
|
|
107
|
+
def insert_values(format_string, replacements)
|
|
108
|
+
format_string.split("\n", -1).map do |line|
|
|
109
|
+
rendered = +""
|
|
110
|
+
separator = ""
|
|
111
|
+
skipped = false
|
|
112
|
+
|
|
113
|
+
line.split(FORMAT_SPLIT_PATTERN, -1).each do |part|
|
|
114
|
+
unless replacements.key?(part)
|
|
115
|
+
# A separator before an empty field usually belongs to
|
|
116
|
+
# the value that came before it, so keep that one.
|
|
117
|
+
separator = part unless skipped
|
|
118
|
+
next
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
if replacements[part].empty?
|
|
122
|
+
skipped = true
|
|
123
|
+
next
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
rendered << separator if !rendered.empty? || !skipped
|
|
127
|
+
rendered << replacements[part]
|
|
128
|
+
separator = ""
|
|
129
|
+
skipped = false
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
rendered
|
|
133
|
+
end.join("\n")
|
|
134
|
+
end
|
|
135
|
+
|
|
102
136
|
# Removes empty lines, leading punctuation, excess whitespace.
|
|
103
137
|
def clean_output(output)
|
|
104
138
|
output.split("\n").map { |line| line.gsub(LEADING_TRAILING_PUNCTUATION_PATTERN, "").strip.gsub(MULTIPLE_SPACES_PATTERN, " ") }.reject(&:empty?).join("\n")
|
|
@@ -116,22 +150,18 @@ module Addressing
|
|
|
116
150
|
AddressField.all.map { |_, field| [field, address.send(field)] }.to_h
|
|
117
151
|
end
|
|
118
152
|
|
|
119
|
-
#
|
|
153
|
+
# Replaces the subdivision values with the codes of any predefined ones.
|
|
120
154
|
def resolve_subdivision_values(values, address, address_format)
|
|
121
|
-
|
|
155
|
+
parents = [address.country_code]
|
|
122
156
|
|
|
123
|
-
|
|
124
|
-
subdivision_fields.each_with_index.inject([{}, []]) do |(original_values, parents), (field, index)|
|
|
157
|
+
address_format.subdivision_fields.each do |field|
|
|
125
158
|
# This level is empty, so there can be no sublevels.
|
|
126
|
-
break if values[field].nil?
|
|
127
|
-
|
|
128
|
-
parents << ((index > 0) ? original_values[subdivision_fields[index - 1]] : address.country_code)
|
|
159
|
+
break if values[field].nil? || values[field].empty?
|
|
129
160
|
|
|
130
161
|
subdivision = Subdivision.get(values[field], parents)
|
|
131
162
|
break if subdivision.nil?
|
|
132
163
|
|
|
133
|
-
|
|
134
|
-
original_values[field] = values[field]
|
|
164
|
+
parents << values[field]
|
|
135
165
|
|
|
136
166
|
# Replace the value with the expected code.
|
|
137
167
|
use_local_name = Locale.match_candidates(address.locale, subdivision.locale)
|
|
@@ -139,8 +169,6 @@ module Addressing
|
|
|
139
169
|
|
|
140
170
|
# The current subdivision has no children, stop.
|
|
141
171
|
break unless subdivision.children?
|
|
142
|
-
|
|
143
|
-
[original_values, parents]
|
|
144
172
|
end
|
|
145
173
|
end
|
|
146
174
|
|
data/lib/addressing/model.rb
CHANGED
|
@@ -46,25 +46,24 @@ module Addressing
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
define_method :verify_subdivisions do |address, address_format, field_overrides|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
parents = [address_format.country_code]
|
|
50
|
+
subdivisions = []
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
address_format.subdivision_fields.each do |field|
|
|
53
|
+
value = address.send(field)
|
|
53
54
|
# The field is empty or validation is disabled.
|
|
54
|
-
break
|
|
55
|
+
break if value.blank? || field_overrides.hidden_fields.include?(field)
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
subdivision = Subdivision.get(address.send(field), parents)
|
|
57
|
+
subdivision = Subdivision.get(value, parents)
|
|
58
58
|
if subdivision.nil?
|
|
59
59
|
errors.add(field, "should be valid")
|
|
60
|
-
break
|
|
60
|
+
break
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
parents << value
|
|
63
64
|
subdivisions << subdivision
|
|
64
65
|
# No predefined subdivisions below this level, stop here.
|
|
65
|
-
break
|
|
66
|
-
|
|
67
|
-
[subdivisions, parents]
|
|
66
|
+
break unless subdivision.children?
|
|
68
67
|
end
|
|
69
68
|
|
|
70
69
|
subdivisions
|
|
@@ -58,8 +58,8 @@ module Addressing
|
|
|
58
58
|
def has_data(parents)
|
|
59
59
|
country_code = parents[0]
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
return false if
|
|
61
|
+
subdivision_fields = AddressFormat.get(country_code).subdivision_fields
|
|
62
|
+
return false if subdivision_fields.empty?
|
|
63
63
|
|
|
64
64
|
if parents.size > 1
|
|
65
65
|
# After the first level it is possible for predefined subdivisions
|
|
@@ -74,8 +74,9 @@ module Addressing
|
|
|
74
74
|
definition = @definitions[parent_group]["subdivisions"][parent_id]
|
|
75
75
|
return !!definition["has_children"]
|
|
76
76
|
else
|
|
77
|
-
# The parent definition wasn't loaded previously, fallback to
|
|
78
|
-
|
|
77
|
+
# The parent definition wasn't loaded previously, fallback to
|
|
78
|
+
# guessing based on the count of subdivision data fields.
|
|
79
|
+
return parents.size <= subdivision_fields.size
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
@@ -98,19 +99,30 @@ module Addressing
|
|
|
98
99
|
filename = File.join(File.expand_path("../../../data/subdivision", __FILE__).to_s, "#{group}.json")
|
|
99
100
|
|
|
100
101
|
if File.exist?(filename)
|
|
101
|
-
|
|
102
|
-
@definitions[group] = JSON.parse(raw_definition)
|
|
103
|
-
@definitions[group] = process_definitions(@definitions[group])
|
|
102
|
+
@definitions[group] = process_definitions(parse_definitions(File.read(filename)))
|
|
104
103
|
end
|
|
105
104
|
end
|
|
106
105
|
|
|
107
106
|
@definitions[group]
|
|
108
107
|
end
|
|
109
108
|
|
|
109
|
+
# Parses a raw definition file.
|
|
110
|
+
#
|
|
111
|
+
# Malformed JSON is treated as if the file didn't exist.
|
|
112
|
+
def parse_definitions(raw_definition)
|
|
113
|
+
definitions = JSON.parse(raw_definition)
|
|
114
|
+
definitions.is_a?(Hash) ? definitions : {}
|
|
115
|
+
rescue JSON::ParserError
|
|
116
|
+
{}
|
|
117
|
+
end
|
|
118
|
+
|
|
110
119
|
# Processes the loaded definitions.
|
|
111
120
|
#
|
|
112
121
|
# Adds keys and values that were removed from the JSON files for brevity.
|
|
113
122
|
def process_definitions(definitions)
|
|
123
|
+
# Malformed definitions are treated as if they didn't exist.
|
|
124
|
+
return {} unless definitions["subdivisions"].is_a?(Hash)
|
|
125
|
+
|
|
114
126
|
definitions["subdivisions"].each do |id, definition|
|
|
115
127
|
# Add common keys from the root level.
|
|
116
128
|
definition["country_code"] = definitions["country_code"]
|
|
@@ -124,6 +136,12 @@ module Addressing
|
|
|
124
136
|
definition["name"] = id
|
|
125
137
|
end
|
|
126
138
|
|
|
139
|
+
# The local_name value is only specified if it doesn't match
|
|
140
|
+
# the name one.
|
|
141
|
+
if definitions.key?("locale") && !definition.key?("local_name")
|
|
142
|
+
definition["local_name"] = definition["name"]
|
|
143
|
+
end
|
|
144
|
+
|
|
127
145
|
# The code and local_code values are only specified if they
|
|
128
146
|
# don't match the name and local_name ones.
|
|
129
147
|
if !definition.key?("code") && definition.key?("name")
|
data/lib/addressing/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: addressing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robin van der Vleuten
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email: robinvdvleuten@gmail.com
|
|
@@ -617,6 +617,8 @@ files:
|
|
|
617
617
|
- data/subdivision/EG.json
|
|
618
618
|
- data/subdivision/ES.json
|
|
619
619
|
- data/subdivision/FM.json
|
|
620
|
+
- data/subdivision/GB.json
|
|
621
|
+
- data/subdivision/GT.json
|
|
620
622
|
- data/subdivision/HK-2705954f46a43ef0ad522412afe6ed6ee8196fe4.json
|
|
621
623
|
- data/subdivision/HK-29ceaf41d01206ba481b188116cbb302b82663cf.json
|
|
622
624
|
- data/subdivision/HK-ff51a84233701e6a1d18f70acf4b3f909e4c6a09.json
|