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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -0
  3. data/README.md +1 -1
  4. data/data/country/af.json +1 -1
  5. data/data/country/ak.json +258 -0
  6. data/data/country/am.json +18 -18
  7. data/data/country/ba.json +258 -0
  8. data/data/country/bn-IN.json +3 -3
  9. data/data/country/bn.json +3 -3
  10. data/data/country/bs.json +1 -0
  11. data/data/country/ca.json +9 -9
  12. data/data/country/cv.json +258 -0
  13. data/data/country/cy.json +1 -1
  14. data/data/country/en-AU.json +16 -16
  15. data/data/country/en-LT.json +258 -0
  16. data/data/country/en-LV.json +258 -0
  17. data/data/country/en-UA.json +258 -0
  18. data/data/country/fil.json +1 -1
  19. data/data/country/fr-CA.json +1 -1
  20. data/data/country/ga.json +17 -17
  21. data/data/country/gd.json +2 -2
  22. data/data/country/gl.json +20 -20
  23. data/data/country/gu.json +12 -12
  24. data/data/country/hr.json +17 -17
  25. data/data/country/hy.json +2 -2
  26. data/data/country/ig.json +30 -30
  27. data/data/country/is.json +1 -1
  28. data/data/country/it.json +8 -8
  29. data/data/country/kk-Arab.json +258 -0
  30. data/data/country/kok.json +158 -158
  31. data/data/country/ky.json +3 -3
  32. data/data/country/lt.json +1 -1
  33. data/data/country/lv.json +9 -9
  34. data/data/country/mk.json +1 -1
  35. data/data/country/ml.json +1 -1
  36. data/data/country/mn.json +9 -9
  37. data/data/country/mr.json +1 -1
  38. data/data/country/or.json +14 -14
  39. data/data/country/pa.json +7 -7
  40. data/data/country/qu.json +258 -0
  41. data/data/country/rm.json +258 -0
  42. data/data/country/shn.json +258 -0
  43. data/data/country/sl.json +16 -16
  44. data/data/country/so.json +2 -2
  45. data/data/country/sr-Cyrl-BA.json +1 -1
  46. data/data/country/sr-Cyrl-ME.json +1 -1
  47. data/data/country/sr-Cyrl-XK.json +1 -1
  48. data/data/country/sr-Latn-BA.json +1 -1
  49. data/data/country/sr-Latn-ME.json +1 -1
  50. data/data/country/sr-Latn-XK.json +1 -1
  51. data/data/country/sr-Latn.json +1 -1
  52. data/data/country/sr.json +1 -1
  53. data/data/country/sw-CD.json +1 -1
  54. data/data/country/sw.json +1 -1
  55. data/data/country/ta.json +3 -3
  56. data/data/country/te.json +11 -11
  57. data/data/country/vi.json +1 -1
  58. data/data/country/yue-Hans.json +11 -11
  59. data/data/country/yue.json +10 -10
  60. data/data/subdivision/VN.json +38 -154
  61. data/lib/addressing/address.rb +66 -78
  62. data/lib/addressing/address_format.rb +19 -8
  63. data/lib/addressing/country.rb +62 -30
  64. data/lib/addressing/default_formatter.rb +33 -19
  65. data/lib/addressing/enum.rb +4 -5
  66. data/lib/addressing/exceptions.rb +29 -0
  67. data/lib/addressing/field_override.rb +6 -13
  68. data/lib/addressing/locale.rb +25 -12
  69. data/lib/addressing/model.rb +0 -6
  70. data/lib/addressing/postal_label_formatter.rb +1 -1
  71. data/lib/addressing/subdivision.rb +36 -22
  72. data/lib/addressing/version.rb +1 -1
  73. data/lib/addressing.rb +1 -8
  74. metadata +17 -6
  75. /data/data/country/{en-ID.json → en-EE.json} +0 -0
  76. /data/data/country/{en-MV.json → en-GE.json} +0 -0
@@ -5,6 +5,7 @@
5
5
  "AR": "阿根廷",
6
6
  "AE": "阿拉伯联合大公国",
7
7
  "OM": "阿曼王国",
8
+ "AZ": "阿塞拜疆",
8
9
  "AC": "阿森松岛",
9
10
  "EG": "埃及",
10
11
  "IE": "爱尔兰",
@@ -30,6 +31,7 @@
30
31
  "BG": "保加利亚",
31
32
  "KP": "北韩",
32
33
  "MP": "北马里亚纳群岛",
34
+ "MK": "北马其顿",
33
35
  "BZ": "贝里斯",
34
36
  "BJ": "贝南",
35
37
  "BE": "比利时",
@@ -74,6 +76,7 @@
74
76
  "CO": "哥伦比亚",
75
77
  "CR": "哥斯大黎加",
76
78
  "GL": "格陵兰",
79
+ "GE": "格鲁吉亚",
77
80
  "GD": "格瑞那达",
78
81
  "KM": "葛摩",
79
82
  "GG": "根西岛",
@@ -114,10 +117,10 @@
114
117
  "LV": "拉脱维亚",
115
118
  "LR": "赖比瑞亚",
116
119
  "LS": "赖索托",
120
+ "LA": "老挝",
117
121
  "LB": "黎巴嫩",
118
122
  "LT": "立陶宛",
119
123
  "LY": "利比亚",
120
- "LA": "寮国",
121
124
  "LI": "列支敦斯登",
122
125
  "RE": "留尼旺",
123
126
  "RW": "卢安达",
@@ -130,7 +133,6 @@
130
133
  "MW": "马拉威",
131
134
  "MY": "马来西亚",
132
135
  "ML": "马利",
133
- "MK": "马其顿",
134
136
  "MH": "马绍尔群岛",
135
137
  "YT": "马约特",
136
138
  "IM": "曼岛",
@@ -163,7 +165,6 @@
163
165
  "NP": "尼泊尔",
164
166
  "NE": "尼日",
165
167
  "NU": "纽埃岛",
166
- "NZ": "纽西兰",
167
168
  "NO": "挪威",
168
169
  "NF": "诺福克岛",
169
170
  "NR": "诺鲁",
@@ -171,7 +172,6 @@
171
172
  "PT": "葡萄牙",
172
173
  "BI": "蒲隆地",
173
174
  "TT": "千里达同多巴哥",
174
- "GE": "乔治亚共和国",
175
175
  "JP": "日本",
176
176
  "SE": "瑞典",
177
177
  "CH": "瑞士",
@@ -181,7 +181,7 @@
181
181
  "SN": "塞内加尔",
182
182
  "SC": "塞席尔",
183
183
  "CY": "赛普勒斯",
184
- "SA": "沙乌地阿拉伯",
184
+ "SA": "沙特阿拉伯",
185
185
  "ZM": "尚比亚",
186
186
  "BL": "圣巴瑟米",
187
187
  "CX": "圣诞岛",
@@ -229,18 +229,18 @@
229
229
  "ZW": "辛巴威",
230
230
  "SG": "新加坡",
231
231
  "NC": "新喀里多尼亚",
232
+ "NZ": "新西兰",
232
233
  "HU": "匈牙利",
233
234
  "EA": "休达与梅利利亚",
234
235
  "SY": "叙利亚",
235
236
  "JM": "牙买加",
236
237
  "AM": "亚美尼亚",
237
- "AZ": "亚塞拜然",
238
- "YE": "叶门",
238
+ "YE": "也门",
239
239
  "IQ": "伊拉克",
240
240
  "IR": "伊朗",
241
241
  "ET": "衣索比亚",
242
242
  "IL": "以色列",
243
- "IT": "义大利",
243
+ "IT": "意大利",
244
244
  "IN": "印度",
245
245
  "ID": "印尼",
246
246
  "GB": "英国",
@@ -252,7 +252,7 @@
252
252
  "GI": "直布罗陀",
253
253
  "CL": "智利",
254
254
  "CF": "中非共和国",
255
- "CN": "中华人民共和国",
256
- "MO": "中华人民共和国澳门特别行政区",
257
- "HK": "中华人民共和国香港特别行政区"
255
+ "CN": "中国",
256
+ "MO": "中国澳门特别行政区",
257
+ "HK": "中国香港特别行政区"
258
258
  }
@@ -1,13 +1,14 @@
1
1
  {
2
+ "YE": "也門",
2
3
  "TT": "千里達同多巴哥",
3
4
  "TR": "土耳其",
4
5
  "TC": "土克斯及開科斯群島",
5
6
  "TM": "土庫曼",
6
7
  "BT": "不丹",
7
8
  "CF": "中非共和國",
8
- "CN": "中華人民共和國",
9
- "HK": "中華人民共和國香港特別行政區",
10
- "MO": "中華人民共和國澳門特別行政區",
9
+ "CN": "中國",
10
+ "HK": "中國香港特別行政區",
11
+ "MO": "中國澳門特別行政區",
11
12
  "DK": "丹麥",
12
13
  "EC": "厄瓜多",
13
14
  "ER": "厄利垂亞",
@@ -67,6 +68,7 @@
67
68
  "AD": "安道爾",
68
69
  "TK": "托克勞群島",
69
70
  "BM": "百慕達",
71
+ "LA": "老撾",
70
72
  "ET": "衣索比亞",
71
73
  "ES": "西班牙",
72
74
  "EH": "西撒哈拉",
@@ -76,13 +78,12 @@
76
78
  "HN": "宏都拉斯",
77
79
  "GR": "希臘",
78
80
  "BN": "汶萊",
79
- "SA": "沙烏地阿拉伯",
81
+ "SA": "沙特阿拉伯",
80
82
  "BZ": "貝里斯",
81
83
  "BJ": "貝南",
82
84
  "GQ": "赤道幾內亞",
83
85
  "ZW": "辛巴威",
84
86
  "AM": "亞美尼亞",
85
- "AZ": "亞塞拜然",
86
87
  "TZ": "坦尚尼亞",
87
88
  "NG": "奈及利亞",
88
89
  "VE": "委內瑞拉",
@@ -110,6 +111,7 @@
110
111
  "OM": "阿曼王國",
111
112
  "AF": "阿富汗",
112
113
  "AC": "阿森松島",
114
+ "AZ": "阿塞拜疆",
113
115
  "DZ": "阿爾及利亞",
114
116
  "AL": "阿爾巴尼亞",
115
117
  "RU": "俄羅斯",
@@ -149,6 +151,7 @@
149
151
  "GG": "根西島",
150
152
  "GL": "格陵蘭",
151
153
  "GD": "格瑞那達",
154
+ "GE": "格魯吉亞",
152
155
  "TH": "泰國",
153
156
  "HT": "海地",
154
157
  "UG": "烏干達",
@@ -159,7 +162,6 @@
159
162
  "RE": "留尼旺",
160
163
  "PE": "秘魯",
161
164
  "NA": "納米比亞",
162
- "NZ": "紐西蘭",
163
165
  "NU": "紐埃島",
164
166
  "SO": "索馬利亞",
165
167
  "SB": "索羅門群島",
@@ -183,7 +185,6 @@
183
185
  "BQ": "荷蘭加勒比區",
184
186
  "MZ": "莫三比克",
185
187
  "CM": "喀麥隆",
186
- "GE": "喬治亞共和國",
187
188
  "GN": "幾內亞",
188
189
  "GW": "幾內亞比索",
189
190
  "FJ": "斐濟",
@@ -202,15 +203,16 @@
202
203
  "RS": "塞爾維亞",
203
204
  "AT": "奧地利",
204
205
  "AX": "奧蘭群島",
206
+ "IT": "意大利",
205
207
  "EE": "愛沙尼亞",
206
208
  "IE": "愛爾蘭",
207
209
  "SG": "新加坡",
210
+ "NZ": "新西蘭",
208
211
  "NC": "新喀里多尼亞",
209
212
  "SL": "獅子山",
210
213
  "CH": "瑞士",
211
214
  "SE": "瑞典",
212
215
  "VU": "萬那杜",
213
- "IT": "義大利",
214
216
  "BL": "聖巴瑟米",
215
217
  "VC": "聖文森特同格林納丁斯",
216
218
  "PM": "聖皮埃爾同密克隆群島",
@@ -220,7 +222,6 @@
220
222
  "SH": "聖赫勒拿島",
221
223
  "CX": "聖誕島",
222
224
  "LC": "聖露西亞",
223
- "YE": "葉門",
224
225
  "KM": "葛摩",
225
226
  "PT": "葡萄牙",
226
227
  "FK": "福克蘭群島",
@@ -231,7 +232,6 @@
231
232
  "BI": "蒲隆地",
232
233
  "GY": "蓋亞那",
233
234
  "HM": "赫德島同麥克唐納群島",
234
- "LA": "寮國",
235
235
  "DE": "德國",
236
236
  "MA": "摩洛哥",
237
237
  "MC": "摩納哥",
@@ -2,51 +2,15 @@
2
2
  "country_code": "VN",
3
3
  "locale": "vi",
4
4
  "subdivisions": {
5
- "44": {
5
+ "91": {
6
6
  "name": "An Giang Province",
7
7
  "local_name": "An Giang"
8
8
  },
9
- "43": {
10
- "name": "Ba Ria-Vung Tau Province",
11
- "local_name": "Bà Rịa–Vũng Tàu"
12
- },
13
- "55": {
14
- "name": "Bac Lieu Province",
15
- "local_name": "Bạc Liêu"
16
- },
17
- "54": {
18
- "name": "Bac Giang Province",
19
- "local_name": "Bắc Giang"
20
- },
21
- "53": {
22
- "name": "Bac Kan Province",
23
- "local_name": "Bắc Kạn"
24
- },
25
- "56": {
9
+ "24": {
26
10
  "name": "Bac Ninh Province",
27
11
  "local_name": "Bắc Ninh"
28
12
  },
29
- "50": {
30
- "name": "Ben Tre Province",
31
- "local_name": "Bến Tre"
32
- },
33
- "57": {
34
- "name": "Binh Duong Province",
35
- "local_name": "Bình Dương"
36
- },
37
- "31": {
38
- "name": "Binh Dinh Province",
39
- "local_name": "Bình Định"
40
- },
41
- "58": {
42
- "name": "Binh Phuoc Province",
43
- "local_name": "Bình Phước"
44
- },
45
- "40": {
46
- "name": "Binh Thuan Province",
47
- "local_name": "Bình Thuận"
48
- },
49
- "59": {
13
+ "96": {
50
14
  "name": "Ca Mau Province",
51
15
  "local_name": "Cà Mau"
52
16
  },
@@ -54,71 +18,55 @@
54
18
  "name": "Cao Bang Province",
55
19
  "local_name": "Cao Bằng"
56
20
  },
57
- "CT": {
21
+ "92": {
58
22
  "name": "Can Tho City",
59
23
  "local_name": "Cần Thơ"
60
24
  },
61
- "DN": {
25
+ "48": {
62
26
  "name": "Da Nang City",
63
27
  "local_name": "Đà Nẵng"
64
28
  },
65
- "33": {
29
+ "66": {
66
30
  "name": "Dak Lak Province",
67
31
  "local_name": "Đắk Lắk"
68
32
  },
69
- "72": {
70
- "name": "Dak Nong Province",
71
- "local_name": "Đăk Nông"
72
- },
73
- "71": {
33
+ "11": {
74
34
  "name": "Dien Bien Province",
75
35
  "local_name": "Điện Biên"
76
36
  },
77
- "39": {
37
+ "75": {
78
38
  "name": "Dong Nai Province",
79
39
  "local_name": "Đồng Nai"
80
40
  },
81
- "45": {
41
+ "82": {
82
42
  "name": "Dong Thap Province",
83
43
  "local_name": "Đồng Tháp"
84
44
  },
85
- "30": {
45
+ "52": {
86
46
  "name": "Gia Lai Province",
87
47
  "local_name": "Gia Lai"
88
48
  },
89
- "03": {
90
- "name": "Ha Giang Province",
91
- "local_name": "Hà Giang"
92
- },
93
- "63": {
94
- "name": "Ha Nam Province",
95
- "local_name": "Hà Nam"
96
- },
97
- "HN": {
49
+ "01": {
98
50
  "name": "Hanoi City",
99
51
  "local_name": "Hà Nội"
100
52
  },
101
- "23": {
53
+ "42": {
102
54
  "name": "Ha Tinh Province",
103
55
  "local_name": "Hà Tĩnh"
104
56
  },
105
- "61": {
106
- "name": "Hai Duong Province",
107
- "local_name": "Hải Dương"
108
- },
109
- "HP": {
110
- "name": "Haiphong City",
57
+ "31": {
58
+ "name": "Hai Phong City",
111
59
  "local_name": "Hải Phòng"
112
60
  },
113
- "73": {
114
- "name": "Hau Giang Province",
115
- "local_name": "Hậu Giang"
61
+ "79": {
62
+ "name": "Ho Chi Minh City",
63
+ "local_name": "Thành phố Hồ Chí Minh"
116
64
  },
117
- "14": {
118
- "name": "Hoa Binh Province",
119
- "local_name": "Hòa Bình"
65
+ "46": {
66
+ "name": "Hue City",
67
+ "local_name": "Huế"
120
68
  },
121
- "66": {
69
+ "56": {
122
70
  "name": "Hung Yen Province",
123
71
  "local_name": "Hưng Yên"
124
72
  },
@@ -126,23 +74,15 @@
126
74
  "name": "Khanh Hoa Province",
127
75
  "local_name": "Khánh Hòa"
128
76
  },
129
- "47": {
130
- "name": "Kien Giang Province",
131
- "local_name": "Kiên Giang"
132
- },
133
- "28": {
134
- "name": "Kon Tum Province",
135
- "local_name": "Kon Tum"
136
- },
137
- "01": {
77
+ "12": {
138
78
  "name": "Lai Chau Province",
139
79
  "local_name": "Lai Châu"
140
80
  },
141
- "09": {
142
- "name": "Lang Song Province",
81
+ "20": {
82
+ "name": "Lang Son Province",
143
83
  "local_name": "Lạng Sơn"
144
84
  },
145
- "02": {
85
+ "68": {
146
86
  "name": "Lao Cai Province",
147
87
  "local_name": "Lào Cai"
148
88
  },
@@ -150,109 +90,53 @@
150
90
  "name": "Lam Dong Province",
151
91
  "local_name": "Lâm Đồng"
152
92
  },
153
- "41": {
154
- "name": "Long An Province",
155
- "local_name": "Long An"
156
- },
157
- "67": {
158
- "name": "Nam Dinh Province",
159
- "local_name": "Nam Định"
160
- },
161
- "22": {
93
+ "40": {
162
94
  "name": "Nghe An Province",
163
95
  "local_name": "Nghệ An"
164
96
  },
165
- "18": {
97
+ "37": {
166
98
  "name": "Ninh Binh Province",
167
99
  "local_name": "Ninh Bình"
168
100
  },
169
- "36": {
170
- "name": "Ninh Thuan Province",
171
- "local_name": "Ninh Thuận"
172
- },
173
- "68": {
101
+ "25": {
174
102
  "name": "Phu Tho Province",
175
103
  "local_name": "Phú Thọ"
176
104
  },
177
- "32": {
178
- "name": "Phu Yen Province",
179
- "local_name": "Phú Yên"
180
- },
181
- "24": {
182
- "name": "Quang Binh Province",
183
- "local_name": "Quảng Bình"
184
- },
185
- "27": {
186
- "name": "Quang Nam Province",
187
- "local_name": "Quảng Nam"
188
- },
189
- "29": {
105
+ "51": {
190
106
  "name": "Quang Ngai Province",
191
107
  "local_name": "Quảng Ngãi"
192
108
  },
193
- "13": {
109
+ "22": {
194
110
  "name": "Quang Ninh Province",
195
111
  "local_name": "Quảng Ninh"
196
112
  },
197
- "25": {
113
+ "44": {
198
114
  "name": "Quang Tri Province",
199
115
  "local_name": "Quảng Trị"
200
116
  },
201
- "52": {
202
- "name": "Soc Trang Province",
203
- "local_name": "Sóc Trăng"
204
- },
205
- "05": {
117
+ "14": {
206
118
  "name": "Son La Province",
207
119
  "local_name": "Sơn La"
208
120
  },
209
- "37": {
121
+ "80": {
210
122
  "name": "Tay Ninh Province",
211
123
  "local_name": "Tây Ninh"
212
124
  },
213
- "20": {
214
- "name": "Thai Binh Province",
215
- "local_name": "Thái Bình"
216
- },
217
- "69": {
125
+ "19": {
218
126
  "name": "Thai Nguyen Province",
219
127
  "local_name": "Thái Nguyên"
220
128
  },
221
- "21": {
129
+ "38": {
222
130
  "name": "Thanh Hoa Province",
223
131
  "local_name": "Thanh Hóa"
224
- },
225
- "SG": {
226
- "name": "Ho Chi Minh City",
227
- "local_name": "Thành phố Hồ Chí Minh"
228
- },
229
- "26": {
230
- "name": "Thua Thien-Hue Province",
231
- "local_name": "Thừa Thiên–Huế"
232
- },
233
- "46": {
234
- "name": "Tien Giang Province",
235
- "local_name": "Tiền Giang"
236
- },
237
- "51": {
238
- "name": "Tra Vinh Province",
239
- "local_name": "Trà Vinh"
240
- },
241
- "07": {
132
+ },
133
+ "08": {
242
134
  "name": "Tuyen Quang Province",
243
135
  "local_name": "Tuyên Quang"
244
136
  },
245
- "49": {
137
+ "86": {
246
138
  "name": "Vinh Long Province",
247
139
  "local_name": "Vĩnh Long"
248
- },
249
- "70": {
250
- "name": "Vinh Phuc Province",
251
- "local_name": "Vĩnh Phúc"
252
- },
253
- "06": {
254
- "name": "Yen Bai Province",
255
- "local_name": "Yên Bái"
256
140
  }
257
141
  }
258
142
  }
@@ -1,9 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Addressing
4
+ # Represents a postal address with attributes for country, administrative areas,
5
+ # postal code, address lines, and recipient information.
6
+ #
7
+ # Address objects are immutable - use the +with_*+ methods to create modified copies.
8
+ #
9
+ # @example Creating an address
10
+ # address = Addressing::Address.new(
11
+ # country_code: "US",
12
+ # administrative_area: "CA",
13
+ # locality: "Mountain View",
14
+ # postal_code: "94043",
15
+ # address_line1: "1600 Amphitheatre Parkway"
16
+ # )
17
+ #
18
+ # @example Modifying an address
19
+ # updated = address.with_postal_code("94044")
4
20
  class Address
5
- attr_reader :country_code, :administrative_area, :locality, :dependent_locality, :postal_code, :sorting_code, :address_line1, :address_line2, :address_line3, :organization, :given_name, :additional_name, :family_name, :locale
6
-
21
+ FIELDS = %i[
22
+ country_code administrative_area locality dependent_locality
23
+ postal_code sorting_code address_line1 address_line2 address_line3
24
+ organization given_name additional_name family_name locale
25
+ ].freeze
26
+
27
+ attr_reader(*FIELDS)
28
+
29
+ # Creates a new Address instance.
30
+ #
31
+ # @param country_code [String] ISO 3166-1 alpha-2 country code
32
+ # @param administrative_area [String] Top-level administrative subdivision (state, province, etc.)
33
+ # @param locality [String] City or locality
34
+ # @param dependent_locality [String] Dependent locality (neighborhood, suburb, district, etc.)
35
+ # @param postal_code [String] Postal code
36
+ # @param sorting_code [String] Sorting code (used in some countries)
37
+ # @param address_line1 [String] First line of the street address
38
+ # @param address_line2 [String] Second line of the street address
39
+ # @param address_line3 [String] Third line of the street address
40
+ # @param organization [String] Organization name
41
+ # @param given_name [String] Given name (first name)
42
+ # @param additional_name [String] Additional name (middle name, patronymic)
43
+ # @param family_name [String] Family name (last name)
44
+ # @param locale [String] Locale code for the address
7
45
  def initialize(country_code: "", administrative_area: "", locality: "", dependent_locality: "", postal_code: "", sorting_code: "", address_line1: "", address_line2: "", address_line3: "", organization: "", given_name: "", additional_name: "", family_name: "", locale: "und")
8
46
  @country_code = country_code
9
47
  @administrative_area = administrative_area
@@ -21,92 +59,42 @@ module Addressing
21
59
  @locale = locale
22
60
  end
23
61
 
24
- def with_country_code(country_code)
25
- address = clone
26
- address.country_code = country_code
27
- address
28
- end
29
-
30
- def with_administrative_area(administrative_area)
31
- address = clone
32
- address.administrative_area = administrative_area
33
- address
34
- end
35
-
36
- def with_locality(locality)
37
- address = clone
38
- address.locality = locality
39
- address
40
- end
41
-
42
- def with_dependent_locality(dependent_locality)
43
- address = clone
44
- address.dependent_locality = dependent_locality
45
- address
46
- end
47
-
48
- def with_postal_code(postal_code)
49
- address = clone
50
- address.postal_code = postal_code
51
- address
52
- end
53
-
54
- def with_sorting_code(sorting_code)
55
- address = clone
56
- address.sorting_code = sorting_code
57
- address
58
- end
59
-
60
- def with_address_line1(address_line1)
61
- address = clone
62
- address.address_line1 = address_line1
63
- address
64
- end
65
-
66
- def with_address_line2(address_line2)
67
- address = clone
68
- address.address_line2 = address_line2
69
- address
62
+ # Define with_* methods for all fields
63
+ FIELDS.each do |field|
64
+ define_method(:"with_#{field}") do |value|
65
+ address = clone
66
+ address.send(:"#{field}=", value)
67
+ address
68
+ end
70
69
  end
71
70
 
72
- def with_address_line3(address_line3)
73
- address = clone
74
- address.address_line3 = address_line3
75
- address
76
- end
77
-
78
- def with_organization(organization)
79
- address = clone
80
- address.organization = organization
81
- address
82
- end
83
-
84
- def with_given_name(given_name)
85
- address = clone
86
- address.given_name = given_name
87
- address
88
- end
71
+ # Compares two addresses for equality based on all field values.
72
+ #
73
+ # @param other [Object] The object to compare with
74
+ # @return [Boolean] true if all fields are equal
75
+ def ==(other)
76
+ return false unless other.is_a?(Address)
89
77
 
90
- def with_additional_name(additional_name)
91
- address = clone
92
- address.additional_name = additional_name
93
- address
78
+ FIELDS.all? { |field| send(field) == other.send(field) }
94
79
  end
95
80
 
96
- def with_family_name(family_name)
97
- address = clone
98
- address.family_name = family_name
99
- address
81
+ # Compares two addresses for equality (alias for ==).
82
+ #
83
+ # @param other [Object] The object to compare with
84
+ # @return [Boolean] true if all fields are equal
85
+ def eql?(other)
86
+ self == other
100
87
  end
101
88
 
102
- def with_locale(locale)
103
- address = clone
104
- address.locale = locale
105
- address
89
+ # Generates a hash code for the address based on all field values.
90
+ #
91
+ # @return [Integer] hash code
92
+ def hash
93
+ FIELDS.map { |field| send(field) }.hash
106
94
  end
107
95
 
108
96
  protected
109
97
 
110
- attr_writer :country_code, :administrative_area, :locality, :dependent_locality, :postal_code, :sorting_code, :address_line1, :address_line2, :address_line3, :organization, :given_name, :additional_name, :family_name, :locale
98
+ attr_writer(*FIELDS)
111
99
  end
112
100
  end