phony 2.15.25 → 2.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/README.textile +35 -7
  3. data/lib/phony/config.rb +91 -0
  4. data/lib/phony/countries/argentina.rb +355 -0
  5. data/lib/phony/countries/austria.rb +32 -24
  6. data/lib/phony/countries/bangladesh.rb +2 -0
  7. data/lib/phony/countries/belarus.rb +2 -0
  8. data/lib/phony/countries/brazil.rb +6 -4
  9. data/lib/phony/countries/cambodia.rb +6 -4
  10. data/lib/phony/countries/china.rb +7 -2
  11. data/lib/phony/countries/croatia.rb +13 -16
  12. data/lib/phony/countries/georgia.rb +6 -4
  13. data/lib/phony/countries/germany.rb +5 -2
  14. data/lib/phony/countries/guinea.rb +8 -5
  15. data/lib/phony/countries/india.rb +2 -0
  16. data/lib/phony/countries/indonesia.rb +7 -2
  17. data/lib/phony/countries/ireland.rb +27 -23
  18. data/lib/phony/countries/italy.rb +30 -17
  19. data/lib/phony/countries/japan.rb +61 -8
  20. data/lib/phony/countries/kyrgyzstan.rb +2 -0
  21. data/lib/phony/countries/latvia.rb +2 -0
  22. data/lib/phony/countries/libya.rb +3 -1
  23. data/lib/phony/countries/malaysia.rb +22 -2
  24. data/lib/phony/countries/moldova.rb +2 -0
  25. data/lib/phony/countries/montenegro.rb +2 -0
  26. data/lib/phony/countries/myanmar.rb +2 -0
  27. data/lib/phony/countries/namibia.rb +2 -0
  28. data/lib/phony/countries/nepal.rb +2 -0
  29. data/lib/phony/countries/netherlands.rb +2 -0
  30. data/lib/phony/countries/pakistan.rb +2 -0
  31. data/lib/phony/countries/paraguay.rb +2 -0
  32. data/lib/phony/countries/russia_kazakhstan_abkhasia_south_ossetia.rb +24 -14
  33. data/lib/phony/countries/saudi_arabia.rb +3 -0
  34. data/lib/phony/countries/serbia.rb +7 -1
  35. data/lib/phony/countries/somalia.rb +5 -1
  36. data/lib/phony/countries/south_korea.rb +16 -9
  37. data/lib/phony/countries/sweden.rb +29 -17
  38. data/lib/phony/countries/taiwan.rb +22 -46
  39. data/lib/phony/countries/tajikistan.rb +2 -0
  40. data/lib/phony/countries/turkmenistan.rb +2 -0
  41. data/lib/phony/countries/ukraine.rb +3 -0
  42. data/lib/phony/countries/united_kingdom.rb +5 -2
  43. data/lib/phony/countries/uruguay.rb +2 -0
  44. data/lib/phony/countries/vietnam.rb +94 -92
  45. data/lib/phony/countries/zimbabwe.rb +2 -0
  46. data/lib/phony/countries.rb +181 -78
  47. data/lib/phony/country.rb +15 -3
  48. data/lib/phony/country_codes.rb +17 -4
  49. data/lib/phony/dsl.rb +5 -3
  50. data/lib/phony/local_splitters/fixed.rb +2 -0
  51. data/lib/phony/national_code.rb +1 -1
  52. data/lib/phony/national_splitters/none.rb +1 -3
  53. data/lib/phony/trunk_code.rb +5 -4
  54. data/lib/phony/vanity.rb +1 -1
  55. data/lib/phony.rb +94 -60
  56. data/spec/functional/config_spec.rb +44 -0
  57. data/spec/functional/plausibility_spec.rb +364 -32
  58. data/spec/lib/phony/countries_spec.rb +245 -52
  59. data/spec/lib/phony/country_codes_spec.rb +106 -33
  60. data/spec/lib/phony/country_spec.rb +54 -15
  61. data/spec/lib/phony/dsl_spec.rb +2 -2
  62. data/spec/lib/phony/local_splitters/regex_spec.rb +12 -5
  63. data/spec/lib/phony/national_splitters/default_spec.rb +1 -1
  64. data/spec/lib/phony/trunk_code_spec.rb +85 -0
  65. data/spec/lib/phony/vanity_spec.rb +30 -0
  66. data/spec/lib/phony_spec.rb +70 -0
  67. metadata +26 -18
@@ -1,4 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  # All countries, ordered by country code.
3
5
  #
4
6
  # Definitions are in the format:
@@ -67,7 +69,7 @@ Phony.define do
67
69
  country '20', one_of('800') >> split(7..7) | # Egypt toll free
68
70
  one_of('3') >> split(7..7) | # Alexandria
69
71
  one_of('2') >> split(8..8) | # Cairo/Giza
70
- one_of('10', '11', '12') >> split(8..8) | # the 3 mobile operators
72
+ one_of('10', '11', '12', '15') >> split(8..8) | # the 4 mobile operators
71
73
  fixed(2) >> split(7..7) # all the other 24 provinces
72
74
 
73
75
  # South Africa.
@@ -94,13 +96,16 @@ Phony.define do
94
96
  # Belgium.
95
97
  #
96
98
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Belgium
99
+ # https://www.bipt.be/operators/publication/national-numbering-plan
97
100
  #
98
101
  country '32', trunk('0') |
99
- match(/^(70|800|90\d)\d+$/) >> split(3,3) | # Service
100
- match(/^(46[0568])\d{6}$/) >> split(2,2,2) | # Mobile (Lycamobile, Telenet, Proximus 0460)
101
- match(/^(4[789]\d)\d{6}$/) >> split(2,2,2) | # Mobile
102
- one_of('2','3','4','9') >> split(3,2,2) | # Short NDCs
103
- fixed(2) >> split(2,2,2) # 2-digit NDCs
102
+ match(/^(7[08])\d+$/) >> split(3,3) | # Premium and national rate Services
103
+ match(/^(800|90\d)\d+$/) >> split(2,3) | # Toll free service and premium numbers
104
+ match(/^(46[056789])\d{6}$/) >> split(2,2,2) | # Mobile (Lycamobile, Telenet, Join Experience, Proximus 0460)
105
+ match(/^(4[789]\d)\d{6}$/) >> split(2,2,2) | # Mobile
106
+ match(/^(45[56])\d{6}$/) >> split(2,2,2) | # Mobile Vikings and Voo
107
+ one_of('2','3','4','9') >> split(3,2,2) | # Short NDCs
108
+ fixed(2) >> split(2,2,2) # 2-digit NDCs
104
109
 
105
110
  # France.
106
111
  #
@@ -121,11 +126,19 @@ Phony.define do
121
126
 
122
127
  # Hungary.
123
128
  #
129
+ # http://webpub-ext.nmhh.hu/aga/foldr/DoIndexAction.do
130
+ #
124
131
  country '36',
125
132
  trunk('06', normalize: false) |
126
- one_of('104','105','107','112') >> split(3,3) | # Service
127
- one_of('1') >> split(3,4) | # Budapest
128
- fixed(2) >> split(3,4) # 2-digit NDCs
133
+ one_of('104', '105', '107', '112') >> split(3,3) | # Service
134
+ one_of('1') >> split(3,4) | # Budapest
135
+ one_of('20', '30', '31', '50', '70') >> split(3,4) | # Mobile
136
+ one_of('21') >> split(3,4) | # VOIP
137
+ one_of('40', '80', '90', '91') >> split(3,3) | # Special charged numbers
138
+ one_of('51') >> split(3,3) | # Corporate network, M2M
139
+ one_of('38') >> split(3,4) | # Corporate network, M2M
140
+ one_of('71') >> split(5,5) | # M2M Numbers
141
+ fixed(2) >> split(3,3) # Geographic numbers
129
142
 
130
143
  # country '39' # Italy, see special file.
131
144
 
@@ -142,7 +155,9 @@ Phony.define do
142
155
  #
143
156
  country '41',
144
157
  trunk('0', normalize: true) |
145
- match(/^(8(00|4[0248]))\d+$/) >> split(3,3)|
158
+ match(/^(860)\d+$/) >> split(2, 3, 2, 2) | # Voice Mail access
159
+ match(/^(8(?:00|4[0248]))\d+$/) >> split(3,3) | # Freecall/Shared Cost
160
+ match(/^(90[016])\d+$/) >> split(3,3) | # Business
146
161
  fixed(2) >> split(3,2,2)
147
162
 
148
163
  # country '43' # Austria, see special file.
@@ -167,17 +182,19 @@ Phony.define do
167
182
  # Note: http://wapedia.mobi/en/Telephone_numbers_in_Poland, mobile not yet correct
168
183
  #
169
184
  country '48',
170
- match(/^(5[013]\d|6[069]\d|7[02389]\d|80[01]|88\d)/) >> split(3,3) |
185
+ match(/^(45\d|5[0137]\d|6[069]\d|7[02389]\d|80[01]|88\d)/) >> split(3,3) |
171
186
  fixed(2) >> split(3,2,2)
172
187
 
173
188
  # country '49' # Germany, see special file.
174
189
 
175
190
  # Peru.
176
- #
191
+ # Note: https://en.wikipedia.org/wiki/Telephone_numbers_in_Peru
192
+ # Note: https://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=PE
177
193
  country '51',
178
194
  one_of('103', '105') >> split(3,3) | # Service.
179
- one_of('1', '9') >> split(4,4) | # Lima and mobile.
180
- fixed(2) >> split(4,4) # 2-digit NDCs.
195
+ one_of('9') >> split(4,4) | # Mobile.
196
+ one_of('1') >> split(3,4) | # Lima.
197
+ fixed(2) >> split(3,3) # 2-digit NDCs.
181
198
 
182
199
  # Mexico.
183
200
  #
@@ -198,14 +215,7 @@ Phony.define do
198
215
  fixed(3) >> split(7) # 3-digit NDCs
199
216
 
200
217
  # Argentine Republic.
201
- #
202
- country '54',
203
- one_of('11', '911') >> split(4,4) | # Fixed & Mobile
204
- match(/^(22[0137]|237|26[14]|29[179]|34[1235]|35[138]|38[1578])/) >> split(3,4) | # Fixed
205
- match(/^(922[0137]|9237|926[14]|929[179]|934[1235]|935[138]|938[1578])/) >> split(3,4) | # Mobile
206
- match(/^(9\d{4})/) >> split(2,4) | # Mobile
207
- match(/^([68]\d{2})/) >> split(3,4) | # Service
208
- fixed(4) >> split(2,4) # Fixed
218
+ # country '54' # argentina, see special file.
209
219
 
210
220
  # Brazil (Federative Republic of).
211
221
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Brazil
@@ -222,6 +232,7 @@ Phony.define do
222
232
  # http://www.itu.int/oth/T020200002C/en
223
233
  country '57',
224
234
  match(/\A(3\d\d)\d+\z/) >> split(3,4) | # mobile (300 310 311 312 313 315 316)
235
+ match(/\A(60\d)\d+\z/) >> split(3,4) |
225
236
  fixed(1) >> split(3,4)
226
237
 
227
238
  # Venezuela (Bolivarian Republic of)
@@ -234,7 +245,7 @@ Phony.define do
234
245
  # Australia.
235
246
  #
236
247
  country '61',
237
- trunk('0') |
248
+ trunk('0', format: false) |
238
249
  match(/^(4\d\d)\d+$/) >> split(3,3) | # Mobile
239
250
  match(/^(1800)\d+$/) >> split(3,3) | # 1800 free call
240
251
  match(/^(1300)\d+$/) >> split(3,3) | # 1300 local rate
@@ -249,9 +260,10 @@ Phony.define do
249
260
  trunk('0') |
250
261
  # 7/10 digits for area code '2'.
251
262
  match(/\A(2)\d{10}\z/) >> split(10) |
263
+ match(/\A(2)\d{8}\z/) >> split(8) |
252
264
  one_of('2') >> split(7) |
253
265
  # mobile
254
- match(/\A(9\d\d)\d{7}\z/) >> split(7) |
266
+ match(/\A([89]\d\d)\d{7}\z/) >> split(7) |
255
267
  match(/\A(9\d\d)\d+\z/) >> split(6) |
256
268
  #
257
269
  fixed(2) >> split(7)
@@ -263,12 +275,17 @@ Phony.define do
263
275
  match(/^(2\d)\d{7}$/) >> split(3,4) | # Mobile
264
276
  match(/^(2\d)\d{6}$/) >> split(3,3) |
265
277
  match(/^(2\d)\d{8}$/) >> split(2,3,3) |
278
+ match(/^(800)\d{6}$/) >> split(3,3) | # International 800 service where agreed
279
+ match(/^(800)\d{7}$/) >> split(3,4) | # International 800 service where agreed
266
280
  fixed(1) >> split(3,4) # Rest
267
281
 
268
282
  # Singapore (Republic of).
269
283
  #
270
284
  country '65',
271
- none >> split(4,4) # TODO Short Codes.
285
+ none >> matched_split(
286
+ /^(800)\d{7}$/ => [3,3,4], # International Toll Free Service (ITFS) and Home Country Direct Service (HCDS) Numbers
287
+ /^\d{8}$/ => [4,4] # TODO Short Codes
288
+ )
272
289
 
273
290
  # Thailand.
274
291
  #
@@ -338,13 +355,13 @@ Phony.define do
338
355
 
339
356
  # Côte d'Ivoire
340
357
  # http://www.wtng.info/wtng-225-ci.html
341
- # http://www.itu.int/dms_pub/itu-t/oth/02/02/T02020000310001PDFE.pdf
358
+ # https://www.itu.int/dms_pub/itu-t/oth/02/02/T02020000310006PDFE.pdf
342
359
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Ivory_Coast
343
360
  #
344
361
  # There is no trunk code for this country and several of the mobile prefixes start with 0
345
362
  country '225',
346
363
  trunk('', :normalize => false) |
347
- fixed(2) >> split(2,2,2)
364
+ fixed(2) >> split(2,2,2,2)
348
365
 
349
366
  country '226', none >> split(4,4) # Burkina Faso http://www.wtng.info/wtng-226-bf.html
350
367
  country '227', none >> split(4,4) # Niger http://www.wtng.info/wtng-227-ne.html
@@ -369,18 +386,25 @@ Phony.define do
369
386
  # Ghana
370
387
  #
371
388
  # From http://www.itu.int/oth/T0202000052/en
389
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Ghana
372
390
  #
373
- country '233', fixed(2) >> split(3,4)
391
+ country '233', trunk('0') | fixed(2) >> split(3,4)
374
392
 
375
393
  # Nigeria
376
- # Wikipedia says 3 4 split, many local number with no splitting
394
+ # 3 4 split for mobile and 1 digit NDC, 3 2 or 3 3 otherwise
395
+ # Many local numbers with no splitting
377
396
  #
378
- # mobile telephony number allocation taken from: http://www.ncc.gov.ng/index.php?option=com_content&view=article&id=113&Itemid=102
397
+ # mobile telephony number allocation taken from:
398
+ # https://www.ncc.gov.ng/technical-regulation/standards/numbering and
399
+ # https://www.itu.int/oth/T020200009C/en
379
400
  country '234',
380
- match(/^([7-9]0\d)\d+$/) >> split(3,4) | # Mobile
381
- match(/^(81\d)\d+$/) >> split(3,4) | # Mobile
382
- one_of('1', '2', '9') >> split(3,4) | # Lagos, Ibadan and Abuja
383
- fixed(2) >> split(3,4) # 2-digit NDC
401
+ match(/^([7-9]0\d)\d+$/) >> split(3,4) | # Mobile
402
+ match(/^(81\d)\d+$/) >> split(3,4) | # Mobile
403
+ match(/^(91\d)\d+$/) >> split(3,4) | # Mobile
404
+ one_of('1', '2') >> split(3,3..4) | # Lagos, Ibadan
405
+ one_of('9') >> split(3,4) | # Abuja
406
+ one_of((30..79).map(&:to_s)) >> split(3,2..3) | # 2-digit NDC
407
+ one_of(%w(82 83 84 85 86 87 88 89)) >> split(3,3) # 2-digit NDC
384
408
 
385
409
  country '235', none >> split(4,4) # Chad http://www.wtng.info/wtng-235-td.html
386
410
  country '236', none >> split(4,4) # Central African Republic http://www.wtng.info/wtng-236-cf.html
@@ -389,8 +413,12 @@ Phony.define do
389
413
  country '239', fixed(1) >> split(3,3) # Sao Tome and Principe, http://www.wtng.info/wtng-239-st.html
390
414
 
391
415
  country '240', none >> split(3,3,3) # Equatorial Guinea
392
- country '241', fixed(1) >> split(3,3) # Gabonese Republic http://www.wtng.info/wtng-241-ga.html
393
- country '242', none >> split(4,5) # Congo http://www.wtng.info/wtng-242-cg.html
416
+ country '241',
417
+ match(/^(\d)\d{6}$/) >> split(3,3) | # Gabonese Republic http://www.wtng.info/wtng-241-ga.html
418
+ match(/^(\d\d)\d{6}$/) >> split(2,2,2) # 2019 update https://en.wikipedia.org/wiki/Telephone_numbers_in_Gabon
419
+ country '242', # Congo http://www.wtng.info/wtng-242-cg.html
420
+ trunk('', :normalize => false) |
421
+ none >> split(4,5)
394
422
  country '243', fixed(2) >> split(3,4) # Democratic Republic of the Congo http://www.wtng.info/wtng-243-cd.html
395
423
  country '244', one_of('321', '348', '358', '363', '364', '485', '526', '535', '546', '612', '643', '652', '655', '722', '726', '728', '729', '777') >> split(3,3) | # Angola
396
424
  fixed(2) >> split(3,4)
@@ -407,9 +435,9 @@ Phony.define do
407
435
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Rwanda
408
436
  country '250',
409
437
  trunk('0') |
410
- one_of('25') >> split(7) | # Geographic, fixed
411
- match(/^(7[238])/) >> split(7) | # Non-geographic, mobile
412
- one_of('06') >> split(6) # Satellite
438
+ one_of('25') >> split(7) | # Geographic, fixed
439
+ match(/^(7[2389])/) >> split(7) | # Non-geographic, mobile
440
+ one_of('06') >> split(6) # Satellite
413
441
 
414
442
  country '251', fixed(2) >> split(3, 4) # Ethiopia http://www.wtng.info/wtng-251-et.html
415
443
 
@@ -459,25 +487,33 @@ Phony.define do
459
487
 
460
488
  # Zambia
461
489
  # http://www.wtng.info/wtng-260-zm.html
490
+ # https://github.com/googlei18n/libphonenumber/
491
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Zambia
492
+
462
493
  country '260',
463
- match(/^(9(55|66|7[7-9]))/) >> split(6) | # mobile
464
- match(/^(21[1-8])/) >> split(6) # fixed
494
+ trunk('0') |
495
+ match(/^(75|76|77|94|95|96|97)/) >> split(3, 4) | # Mobile
496
+ match(/^(800)/) >> split(3,3) | # Toll free
497
+ match(/^(21[1-8])/) >> split(6) # Fixed
465
498
 
466
- # Madagascar http://www.wtng.info/wtng-261-mg.html
499
+ # Madagascar
500
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Madagascar
467
501
  # http://www.itu.int/oth/T020200007F/en
468
502
  country '261',
469
- none >> matched_split(
470
- /\A200\d+\z/ => [2,3,3,3], # Telecom Malagasy (Telma)
471
- /\A20\d+\z/ => [2,3,4], # Telecom Malagasy (Telma)
472
- /\A23\d+\z/ => [2,3,4], # Digitel
473
- /\A30\d+\z/ => [2,3,4], # mobile Madamobil (CDMA2000)
474
- /\A31\d+\z/ => [2,3,4], # mobile Sacel
475
- /\A32\d+\z/ => [2,3,4], # mobile Orange Madagascar
476
- /\A34\d+\z/ => [2,3,4], # mobile Telecom Malagasy (Telma)
477
- /\A5\d+\z/ => [3,3,3], # pager
478
- /\A22\d+\z/ => [3,3,3], # satellite GULFSAT Téléphonie
479
- /\A6\d+\z/ => [3,3,3] # satellite
480
- )
503
+ # none >> matched_split(
504
+ # /\A20\d+\z/ => [2,2,3,2], # Telecom Malagasy (Telma)
505
+ # /\A32\d+\z/ => [2,2,3,2], # mobile Orange Madagascar
506
+ # /\A33\d+\z/ => [2,2,3,2], # mobile Airtel Madagascar
507
+ # /\A34\d+\z/ => [2,2,3,2], # mobile Telecom Malagasy (Telma)
508
+ # /\A38\d+\z/ => [2,2,3,2], # mobile Telecom Malagasy (Telma)
509
+ # /\A39\d+\z => [2,2,3,2] # mobile Blueline
510
+ # ),
511
+ match(/\A(20)\d+\z/) >> split(2,3,2) | # fix Telecom Malagasy (Telma)
512
+ match(/\A(32)\d+\z/) >> split(2,3,2) | # mobile Orange Madagascar
513
+ match(/\A(33)\d+\z/) >> split(2,3,2) | # mobile Airtel Madagascar
514
+ match(/\A(34)\d+\z/) >> split(2,3,2) | # mobile Telecom Malagasy (Telma)
515
+ match(/\A(38)\d+\z/) >> split(2,3,2) | # mobile Telecom Malagasy (Telma)
516
+ match(/\A(39)\d+\z/) >> split(2,3,2) # mobile Blueline Madagascar
481
517
 
482
518
  country '262', # Reunion / Mayotte (new) http://www.wtng.info/wtng-262-fr.html
483
519
  trunk('0') |
@@ -612,8 +648,12 @@ Phony.define do
612
648
  # country '353' # Republic of Ireland, see special file.
613
649
 
614
650
  country '354', none >> split(3,4) # Iceland
651
+
652
+ # Albania
653
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Albania
615
654
  country '355', trunk('0') |
616
- one_of('4') >> split(4,3) | # Albania
655
+ one_of('4') >> split(3,4) | # Tirana
656
+ match(/\A(6[6-9])\d*\z/) >> split(3,4) | # mobile
617
657
  match(/\A(2[24]|3[2-5]|47|5[2-5]|6[6-9]|8[2-5])\d*\z/) >> split(3,3) |
618
658
  fixed(3) >> split(3,2)
619
659
 
@@ -634,17 +674,48 @@ Phony.define do
634
674
  #
635
675
  country '358',
636
676
  trunk('0') |
637
- match(/^([1-3]0)\d+$/) >> split(3,3,0..6) | # Service/subscriber
638
- match(/^([6-8]00)\d+$/) >> split(3,3) | # Service
639
- match(/^(457|4\d|50)\d+$/) >> split(3,2,0..2) | # Mobile
640
- one_of('2','3','5','6','8','9') >> split(3,2..4) | # Short NDCs
641
- fixed(2) >> split(3,3) # 2-digit NDCs
677
+ match(/^(600[3-5]\d|601\d\d|700[3457]\d|7500[12]|7532[12]|7575[12]|7598[12])\d{3,4}$/) >> split(3..4) | # national service numbers, 5-digit NDC
678
+ match(/^(753[02][3-9]|7575[3-9]|7598[3-9])\d{3,5}$/) >> split(3..5) | # national subscriber numbers, 5-digit NDC
679
+ match(/^(73[0-4]\d\d)\d{5}$/) >> split(5) | # national subscriber numbers, 5-digit NDC (starting with 073)
680
+ match(/^(202[023]|209[8-9]|600[0126-9]|700[0126]|7099|800\d)\d{4,5}$/) >> split(2, 2..3) | # national service numbers, 4-digit NDCs
681
+ match(/^(606\d|70[78]\d)\d{6}$/) >> split(3, 3) | # national service numbers, 4-digit NDCs (starting with 0606/0707/0708)
682
+ match(/^(202[14-9]|209[0-7])\d{4,6}$/) >> split(3, 1..3) | # national subscriber numbers, 4-digit NDCs
683
+ match(/^(45[45789]\d)\d{2,6}$/) >> split(2, 0..4) | # mobile numbers, 4-digit NDCs
684
+ match(/^([123]00|602)\d{5,6}$/) >> split(3, 2..3) | # national service numbers, 3-digit NDCs
685
+ match(/^(10[1-9]|20[13-8]|30[1-9]|73[5-9])\d{5,7}$/) >> split(3, 2..4) | # national subscriber numbers, 3-digit NDCs
686
+ match(/^(71\d)\d{6}$/) >> split(3, 3) | # national subscriber numbers, 3-digit NDCs (starting with 071)
687
+ match(/^(73[5-9])\d{7}$/) >> split(3, 4) | # national subscriber numbers, 3-digit NDCs (starting with 073)
688
+ match(/^(43\d|45[0-36])\d{5,7}$/) >> split(3, 2..4) | # mobile numbers, 3-digit NDCs
689
+ match(/^(49\d)\d{8}$/) >> split(3, 3, 2) | # mobile numbers, 3-digit NDCs (starting with 049)
690
+ match(/^([235]9)\d{6,8}$/) >> split(3, 3, 0..2) | # national subscriber numbers, 2-digit NDCs
691
+ match(/^(4[0124678]|50)\d{4,8}$/) >> split(3, 1..5) | # mobile numbers, 2-digit NDCs
692
+ one_of('2','3','5','6','8','9') >> split(3,1..5) | # Short NDCs
693
+ fixed(2) >> split(3, 0..4) # 2-digit NDCs
642
694
 
643
695
  # Bulgaria
644
696
  #
697
+ # Note: https://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=BG
698
+ # Note: https://en.wikipedia.org/wiki/Telephone_numbers_in_Bulgaria
645
699
  country '359',
646
700
  trunk('0') |
647
- fixed(2) >> split(3,2,2) # Bulgaria
701
+ match(/^(2)\d{6}$/) >> split(3,3) | # Landline Sofia (optional last digit)
702
+ match(/^(2)\d{7}$/) >> split(3,4) | # Landline Sofia (optional last digit)
703
+ match(/^(30|31|33|36|37|39|41|43\d|45|47|51|53|55|57|59)\d{5}$/) >> split(5) |
704
+ match(/^(30|31|32|33|34|35|36|37|38|39|41|42|44|45|46|47|51|52|53|54|55|56|57|58|59)\d{6}$/) >> split(2,4) |
705
+
706
+ match(/^(60|61|63|65|66|69)\d{5}$/) >> split(5) |
707
+ match(/^(60|61|62|63|64|65|66|68|69)\d{6}$/) >> split(6) |
708
+
709
+ match(/^(700|701|703|704|705|706|707|708|709)\d{5}$/) >> split(5) |
710
+ match(/^(701|702|703|704|705|706|707|708|709)\d{4}$/) >> split(4) |
711
+
712
+ match(/^(71|72|74|75|77)\d{5}$/) >> split(5) |
713
+ match(/^(71|72|73|74|75|76|77|78|79)\d{6}$/) >> split(6) |
714
+
715
+ match(/^(80\d|81|91|93|95|97)\d{5}$/) >> split(5) |
716
+ match(/^(81|82|84|86)\d{6}$/) >> split(6) |
717
+ match(/^(87|88|89)\d{7}$/) >> split(4,3) |
718
+ match(/^(90|91|92|93|94|95|96|97|98\d|99\d)\d{6}$/) >> split(6)
648
719
 
649
720
  # Lithuania
650
721
  #
@@ -678,11 +749,12 @@ Phony.define do
678
749
  # Monaco
679
750
  #
680
751
  country '377',
681
- one_of('6') >> split(2,2,2,2) | # mobile
752
+ one_of('6') >> split(2,2,2,2) | # mobile
682
753
  fixed(2) >> split(2,2,2)
683
754
 
684
755
  # San Marino
685
756
  country '378',
757
+ trunk('', :normalize => false) |
686
758
  none >> matched_split(
687
759
  /\A\d{6}\z/ => [3,3],
688
760
  /\A\d+\z/ => [3,3,4]
@@ -696,7 +768,13 @@ Phony.define do
696
768
 
697
769
  # country '382' # Montenegro, see special file
698
770
 
699
- country '383', todo # -
771
+ # Kosovo
772
+ #
773
+ # Note: https://en.wikipedia.org/wiki/Telephone_numbers_in_Kosovo
774
+ country '383',
775
+ trunk('0') |
776
+ fixed(2) >> split(3,3)
777
+
700
778
  country '384', todo # -
701
779
 
702
780
  # country '385' # Croatia, see special file.
@@ -710,7 +788,7 @@ Phony.define do
710
788
  one_of('1','2','3','4','5','7') >> split(3,4) | # Ljubljana, Maribor, Celje, Kranj, Nova Gorica, Novo mesto
711
789
  fixed(3) >> split(2,3) # catchall
712
790
 
713
- country '387', trunk('0') | fixed(2) >> split(3,2,2) # Bosnia and Herzegovina
791
+ country '387', trunk('0') | fixed(2) >> split(3,3) # Bosnia and Herzegovina
714
792
  country '388', trunk('0') | fixed(2) >> split(3,2,2) # Group of countries, shared code
715
793
 
716
794
  # The Former Yugoslav Republic of Macedonia
@@ -722,9 +800,11 @@ Phony.define do
722
800
 
723
801
  # Slovak Republic.
724
802
  #
725
- country '421', match(/^(9\d\d).+$/) >> split(6) | # Mobile
726
- one_of('2') >> split(8) | # Bratislava
727
- fixed(2) >> split(7) # 2-digit NDCs
803
+ country '421', match(/^(9\d\d).+$/) >> split(6) | # Mobile
804
+ match(/\A(2)1\d{2,4}\z/) >> split(3..5) | # Bratislava Short
805
+ match(/\A(\d{2})1\d{2,4}\z/) >> split(3..5) | # 2-digit NDCs Short
806
+ one_of('2') >> split(8) | # Bratislava
807
+ fixed(2) >> split(7) # 2-digit NDCs
728
808
 
729
809
  country '422', todo # Spare code
730
810
  country '423', none >> split(3,2,2) # Liechtenstein (Principality of)
@@ -796,7 +876,14 @@ Phony.define do
796
876
  one_of(%w(11 16 17 18 19)) >> split(3) | # audiotext
797
877
  fixed(3) >> split(4) # geographic, audiotext
798
878
 
799
- country '593', fixed(2) >> split(3, 4) # Ecuador http://www.wtng.info/wtng-593-ec.html
879
+ # Ecuador http://www.wtng.info/wtng-593-ec.html
880
+ # https://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=EC&current_page=1
881
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Ecuador
882
+ country '593',
883
+ one_of('9') >> split(4,4) |
884
+ match(/\A([\d]{2})\d{7}\z/) >> split(3,4) |
885
+ fixed(1) >> split(3,4)
886
+
800
887
  country '594', fixed(3) >> split(3, 3) # French Guiana (French Department of) http://www.wtng.info/wtng-594-fr.html
801
888
 
802
889
  # country '595' # Paraguay (Republic of), see special file
@@ -842,7 +929,14 @@ Phony.define do
842
929
  one_of('115') >> split(4,4) | # voicemail (mobile)
843
930
  one_of(%w(28 29)) >> split(3,2) | # pager
844
931
  one_of(%w(16 18)) >> split(3,2) | # ISP
845
- one_of(%w(71 72 73 76)) >> split(3,3) | # mobile
932
+ one_of(%w(70 71 72 74 75 76 78 79)) >> split(3,3) | # mobile
933
+ one_of(%w(731 732 733 734 735 736 738 739)) >> split(2,3) | # mobile
934
+ one_of(%w(770)) >> split(2,3) | # wireless geographic; Port Moresby, National Capital District
935
+ one_of(%w(771)) >> split(2,3) | # wireless geographic; Momase region
936
+ one_of(%w(772)) >> split(2,3) | # wireless geographic; Highlands region
937
+ one_of(%w(7730)) >> split(1,3) | # wireless geographic; Southern region
938
+ one_of(%w(774)) >> split(2,3) | # wireless geographic; Islands region
939
+ one_of(%w(775)) >> split(2,3) | # mobile
846
940
  one_of(%w(80 81 82 83)) >> split(3,3) | # freephone
847
941
  one_of(%w(90 91 92 93)) >> split(3,3) | # geographic, ISDN
848
942
  one_of(%w(3 4 5 6 7 8 9)) >> split(3,3) # geographic
@@ -885,7 +979,7 @@ Phony.define do
885
979
  /\A800\d+\z/ => [3,3], # freephone
886
980
  /\A830\d+\z/ => [3,3], # shared cost
887
981
  /\A60\d+\z/ => [3,3], # wireless geographic
888
- /\A(72|75|76|77)\d+\z/ => [3,4], # mobile
982
+ /\A(71|72|75|76|77)\d+\z/ => [3,4], # mobile
889
983
  /\A84\d+\z/ => [3,4], # wireless geographic
890
984
  /\A\d+\z/ => [2,3] # geographic
891
985
  )
@@ -906,7 +1000,10 @@ Phony.define do
906
1000
  country '698', todo # -
907
1001
  country '699', todo # -
908
1002
 
909
- country '800', todo # International Freephone Service
1003
+ # International Freephone Service
1004
+ # https://www.itu.int/en/ITU-T/inr/unum/Pages/uifn.aspx
1005
+ country '800', none >> split(8)
1006
+
910
1007
  country '801', todo # -
911
1008
  country '802', todo # -
912
1009
  country '803', todo # -
@@ -914,7 +1011,7 @@ Phony.define do
914
1011
  country '805', todo # -
915
1012
  country '806', todo # -
916
1013
  country '807', todo # -
917
- country '808', todo # International Shared Cost Service (ISCS)
1014
+ country '808', none >> split(12) # International Shared Cost Service (ISCS)
918
1015
  country '809', todo # -
919
1016
 
920
1017
  country '830', todo # -
@@ -945,12 +1042,14 @@ Phony.define do
945
1042
  # Hong Kong, China
946
1043
 
947
1044
  country '852',
1045
+ match(/^(800)\d+$/) >> split(2, 4) |
948
1046
  none >> split(4,4)
949
1047
 
950
1048
  # Macao, China
951
1049
  country '853', # Macao, China
952
1050
  match(/^(28)\d+$/) >> split(2,4) | # Landline.
953
- match(/^(6)\d+$/) >> split(3,4) # Mobile.
1051
+ match(/^(8)\d+$/) >> split(3,4) | # Landline.
1052
+ match(/^(6)\d+$/) >> split(3,4) # Mobile.
954
1053
 
955
1054
  country '854', todo # Spare code
956
1055
 
@@ -978,7 +1077,10 @@ Phony.define do
978
1077
  # Bangladesh (People's Republic of)
979
1078
  # country '880' # see special file
980
1079
 
981
- country '881', todo # International Mobile, shared code
1080
+ # Global Mobile Satellite System (i.e. Iridium, Globalstar, etc)
1081
+ # https://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=QM
1082
+ country '881', fixed(1) >> split(3,5)
1083
+
982
1084
  country '882', todo # International Networks, shared code
983
1085
  country '883', todo # -
984
1086
  country '884', todo # -
@@ -1089,17 +1191,18 @@ Phony.define do
1089
1191
  one_of(%w(500 700 900)) >> split(3,3) | # premium rate
1090
1192
  one_of('800') >> matched_split(
1091
1193
  /\A\d{2}\z/ => [2],
1194
+ /\A\d{7}\z/ => [2,3,2],
1092
1195
  /\A\d+\z/ => [2,3,4]) | # freephone
1093
- one_of(%w(50 52 55 56)) >> split(3,4) | # mobile
1196
+ one_of(%w(50 52 54 55 56 58)) >> split(3,4) | # mobile
1094
1197
  one_of(%w(2 3 4 6 7 9)) >> split(3,4) |
1095
1198
  fixed(1) >> split(3,4)
1096
1199
 
1097
1200
  # Israel (State of) (also works for numbers in Palestinian territories)
1098
1201
  country '972',
1099
1202
  trunk('0') |
1100
- one_of('1') >> split(3,3,3) | # special numbers
1101
- one_of('2', '3', '4', '8', '9') >> split(3,4) | # 1 digit ndc
1102
- match(/^(5[023456789]|7[23467])\d+$/) >> split(3,4) # 2 digit ndc
1203
+ one_of('1') >> split(3,3,3) | # special numbers
1204
+ one_of('2', '3', '4', '8', '9') >> split(3,4) | # 1 digit ndc
1205
+ match(/^(5[012345689]|7[234679])\d+$/) >> split(3,4) # 2 digit ndc
1103
1206
 
1104
1207
  country '973', none >> split(4,4..4) # Bahrain (Kingdom of) http://www.itu.int/oth/T0202000011/en
1105
1208
 
data/lib/phony/country.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Phony
2
4
 
3
5
  #
@@ -95,6 +97,9 @@ module Phony
95
97
  end
96
98
  end
97
99
  def format_cc_ndc trunk, ndc, local, type, space, parentheses, use_trunk
100
+ # Note: We mark NDCs that are of type "none" with false (nil trips plausible?). This would result in false being printed.
101
+ # Therefore we set NDC to nil when formatting.
102
+ ndc = nil if ndc == false
98
103
  case type
99
104
  when String
100
105
  trunk &&= trunk.format(space, use_trunk)
@@ -123,6 +128,7 @@ module Phony
123
128
  end
124
129
  end
125
130
  def format_ndc ndc, parentheses
131
+ ndc = nil if ndc == false # TODO
126
132
  parentheses ? "(#{ndc})" : ndc
127
133
  end
128
134
  def format_with_ndc format, cc, ndc, local, space
@@ -154,10 +160,12 @@ module Phony
154
160
  #
155
161
  # In some cases it doesn't, like Italy.
156
162
  #
157
- def normalize national_number
163
+ # Note: Options such as CC
164
+ #
165
+ def normalize national_number, options = {}
158
166
  clean! national_number
159
167
  normalized = @codes.reduce national_number do |number, code|
160
- result = code.normalize number
168
+ result = code.normalize number, options
161
169
  break result if result
162
170
  number
163
171
  end
@@ -168,7 +176,7 @@ module Phony
168
176
  #
169
177
  def plausible? rest, hints = {}
170
178
  local, _, ndc, *rest = internal_split rest
171
-
179
+
172
180
  # Element based checking.
173
181
  #
174
182
  # Note: ndc == false means the country has none.
@@ -185,6 +193,10 @@ module Phony
185
193
  #
186
194
  ndc_needed = hints[:ndc]
187
195
  return false if ndc_needed && !(ndc_needed === ndc)
196
+
197
+ # If there is no local part, we can assume it's not a plausible number.
198
+ # (Or, not defined correctly in Phony yet)
199
+ return false unless local
188
200
 
189
201
  # Local code specific checks.
190
202
  #
@@ -1,6 +1,6 @@
1
1
  module Phony
2
2
 
3
- EMPTY_STRING = ''
3
+ EMPTY_STRING = '' unless defined?(EMPTY_STRING)
4
4
 
5
5
  # Handles determining the correct national code handler.
6
6
  #
@@ -66,7 +66,7 @@ module Phony
66
66
  country, cc, number = partial_split number
67
67
  country
68
68
  end
69
- number = country.normalize number
69
+ number = country.normalize number, cc: cc
70
70
  countrify! number, cc
71
71
  end
72
72
 
@@ -77,7 +77,7 @@ module Phony
77
77
  country, cc, national_number = partial_split number
78
78
 
79
79
  # Split the national number into ndc and local part.
80
- trunk, ndc, *local = country.split national_number
80
+ _, ndc, *local = country.split national_number
81
81
 
82
82
  [cc, ndc, *local]
83
83
  end
@@ -97,9 +97,20 @@ module Phony
97
97
 
98
98
  # False if it fails the basic check.
99
99
  #
100
- return false unless (4..15) === normalized.size
100
+ return false unless (4..16) === normalized.size # unless hints[:check_length] == false
101
101
 
102
102
  country, cc, rest = partial_split normalized
103
+
104
+ # Was a country calling code given?
105
+ #
106
+ if ccc = hints[:ccc]
107
+ cc, ndc, *local = split ccc
108
+
109
+ raise ArgumentError.new("The provided ccc option is too long and includes more than a cc ('#{cc}') and ndc ('#{ndc}'). It also includes '#{local.join}'.") unless local.size == 1 && local[0].empty?
110
+
111
+ hints[:cc] = cc
112
+ hints[:ndc] = ndc
113
+ end
103
114
 
104
115
  # Country code plausible?
105
116
  #
@@ -109,6 +120,8 @@ module Phony
109
120
  # Country specific tests.
110
121
  #
111
122
  country.plausible? rest, hints
123
+ rescue ArgumentError
124
+ raise
112
125
  rescue StandardError
113
126
  return false
114
127
  end
data/lib/phony/dsl.rb CHANGED
@@ -12,9 +12,9 @@ module Phony
12
12
  #
13
13
  # Phony.define.country ...
14
14
  #
15
- def self.define
15
+ def self.define(&block)
16
16
  dsl = DSL.new
17
- dsl.instance_eval(&Proc.new) if block_given?
17
+ dsl.instance_eval(&block) if block_given?
18
18
  dsl
19
19
  end
20
20
 
@@ -41,6 +41,8 @@ module Phony
41
41
  # country '27', # CC, followed by rules, for example fixed(2) >> ...
42
42
  #
43
43
  def country country_code, definition, options = {}
44
+ return unless Phony.config.load?(country_code)
45
+
44
46
  definition.with country_code, options
45
47
  Phony::CountryCodes.instance.add country_code, definition
46
48
  end
@@ -139,7 +141,7 @@ module Phony
139
141
  #
140
142
  ndcs = ndcs.first if Array === ndcs.first
141
143
 
142
- NationalSplitters::Variable.new options[:max_length], ndcs
144
+ NationalSplitters::Variable.new options[:max_length], ndcs.map(&:freeze)
143
145
  end
144
146
 
145
147
  # If you have a number of (possibly) variable length NDCs