phony 2.20.14 → 2.21.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/README.textile +1 -1
- data/lib/phony/config.rb +25 -26
- data/lib/phony/countries/argentina.rb +311 -314
- data/lib/phony/countries/austria.rb +71 -72
- data/lib/phony/countries/bangladesh.rb +27 -28
- data/lib/phony/countries/belarus.rb +110 -111
- data/lib/phony/countries/brazil.rb +92 -92
- data/lib/phony/countries/cambodia.rb +9 -9
- data/lib/phony/countries/china.rb +22 -21
- data/lib/phony/countries/croatia.rb +6 -5
- data/lib/phony/countries/georgia.rb +84 -84
- data/lib/phony/countries/germany.rb +4067 -4068
- data/lib/phony/countries/guinea.rb +8 -8
- data/lib/phony/countries/india.rb +31 -34
- data/lib/phony/countries/indonesia.rb +57 -46
- data/lib/phony/countries/ireland.rb +4 -5
- data/lib/phony/countries/italy.rb +54 -53
- data/lib/phony/countries/japan.rb +456 -456
- data/lib/phony/countries/kyrgyzstan.rb +109 -109
- data/lib/phony/countries/latvia.rb +34 -34
- data/lib/phony/countries/libya.rb +106 -106
- data/lib/phony/countries/malaysia.rb +12 -12
- data/lib/phony/countries/moldova.rb +42 -42
- data/lib/phony/countries/montenegro.rb +24 -20
- data/lib/phony/countries/myanmar.rb +39 -39
- data/lib/phony/countries/namibia.rb +35 -29
- data/lib/phony/countries/nepal.rb +60 -62
- data/lib/phony/countries/netherlands.rb +13 -13
- data/lib/phony/countries/pakistan.rb +134 -110
- data/lib/phony/countries/paraguay.rb +135 -135
- data/lib/phony/countries/russia_kazakhstan_abkhasia_south_ossetia.rb +125 -128
- data/lib/phony/countries/saudi_arabia.rb +5 -5
- data/lib/phony/countries/serbia.rb +47 -39
- data/lib/phony/countries/somalia.rb +18 -18
- data/lib/phony/countries/south_korea.rb +16 -13
- data/lib/phony/countries/sweden.rb +28 -28
- data/lib/phony/countries/taiwan.rb +20 -19
- data/lib/phony/countries/tajikistan.rb +70 -70
- data/lib/phony/countries/turkmenistan.rb +65 -65
- data/lib/phony/countries/ukraine.rb +607 -607
- data/lib/phony/countries/united_kingdom.rb +66 -66
- data/lib/phony/countries/uruguay.rb +40 -41
- data/lib/phony/countries/vietnam.rb +18 -17
- data/lib/phony/countries/zimbabwe.rb +31 -31
- data/lib/phony/countries.rb +440 -443
- data/lib/phony/country.rb +42 -44
- data/lib/phony/country_codes.rb +66 -60
- data/lib/phony/dsl.rb +23 -26
- data/lib/phony/local_splitters/fixed.rb +20 -29
- data/lib/phony/local_splitters/regex.rb +28 -31
- data/lib/phony/national_code.rb +7 -10
- data/lib/phony/national_splitters/default.rb +9 -11
- data/lib/phony/national_splitters/dsl.rb +8 -18
- data/lib/phony/national_splitters/fixed.rb +11 -14
- data/lib/phony/national_splitters/none.rb +7 -11
- data/lib/phony/national_splitters/regex.rb +13 -17
- data/lib/phony/national_splitters/variable.rb +36 -38
- data/lib/phony/trunk_code.rb +16 -18
- data/lib/phony/vanity.rb +12 -13
- data/lib/phony.rb +84 -84
- metadata +5 -39
- data/spec/functional/config_spec.rb +0 -44
- data/spec/functional/plausibility_spec.rb +0 -689
- data/spec/lib/phony/countries_spec.rb +0 -1460
- data/spec/lib/phony/country_codes_spec.rb +0 -227
- data/spec/lib/phony/country_spec.rb +0 -104
- data/spec/lib/phony/dsl_spec.rb +0 -28
- data/spec/lib/phony/local_splitters/fixed_spec.rb +0 -56
- data/spec/lib/phony/local_splitters/regex_spec.rb +0 -94
- data/spec/lib/phony/national_code_spec.rb +0 -61
- data/spec/lib/phony/national_splitters/default_spec.rb +0 -34
- data/spec/lib/phony/national_splitters/fixed_spec.rb +0 -45
- data/spec/lib/phony/national_splitters/none_spec.rb +0 -28
- data/spec/lib/phony/national_splitters/regex_spec.rb +0 -23
- data/spec/lib/phony/national_splitters/variable_spec.rb +0 -35
- data/spec/lib/phony/trunk_code_spec.rb +0 -85
- data/spec/lib/phony/vanity_spec.rb +0 -30
- data/spec/lib/phony_spec.rb +0 -70
data/lib/phony/country.rb
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Phony
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
4
|
class Country
|
8
|
-
|
9
5
|
attr_accessor :codes
|
10
6
|
|
11
7
|
@@international_absolute_format = '+%s%s%s%s%s'
|
12
8
|
@@international_relative_format = '00%s%s%s%s%s'
|
13
9
|
@@national_format = '%s%s%s%s'
|
14
|
-
|
10
|
+
|
15
11
|
@@default_space = ' '
|
16
12
|
@@default_local_space = ' '
|
17
13
|
@@default_parentheses = false
|
18
14
|
|
19
|
-
# TODO Doc.
|
15
|
+
# TODO: Doc.
|
20
16
|
#
|
21
17
|
def initialize *codes
|
22
18
|
@codes = codes
|
@@ -26,8 +22,8 @@ module Phony
|
|
26
22
|
#
|
27
23
|
# Chain two codes together.
|
28
24
|
#
|
29
|
-
def |
|
30
|
-
self.codes =
|
25
|
+
def |(other)
|
26
|
+
self.codes = codes + other.codes
|
31
27
|
self
|
32
28
|
end
|
33
29
|
|
@@ -35,11 +31,11 @@ module Phony
|
|
35
31
|
#
|
36
32
|
# TODO Rewrite.
|
37
33
|
#
|
38
|
-
def with
|
34
|
+
def with(cc, options = {})
|
39
35
|
@cc = cc
|
40
|
-
|
36
|
+
|
41
37
|
@invalid_ndcs = options[:invalid_ndcs]
|
42
|
-
|
38
|
+
|
43
39
|
@format = options[:format]
|
44
40
|
@space = options[:space]
|
45
41
|
@local_space = options[:local_space]
|
@@ -52,43 +48,45 @@ module Phony
|
|
52
48
|
#
|
53
49
|
# @return [Trunk, String (ndc), Array<String> (national pieces)]
|
54
50
|
#
|
55
|
-
def split
|
51
|
+
def split(national_number)
|
56
52
|
_, trunk, ndc, *rest = internal_split national_number
|
57
53
|
[trunk, ndc, *rest]
|
58
54
|
end
|
55
|
+
|
59
56
|
#
|
60
57
|
#
|
61
58
|
# @return [Splitters::Local, Trunk, String (ndc), Array<String> (national pieces)]
|
62
59
|
#
|
63
|
-
def internal_split
|
60
|
+
def internal_split(national_number)
|
64
61
|
trunk = nil
|
65
62
|
@codes.each do |national_splitter|
|
66
63
|
new_trunk, ndc, *rest = national_splitter.split national_number
|
67
64
|
trunk ||= new_trunk
|
68
65
|
return [national_splitter.local_splitter, trunk, ndc, *rest] if rest && !rest.empty?
|
69
66
|
end
|
70
|
-
|
67
|
+
|
71
68
|
# Best effort.
|
72
69
|
[nil, trunk, national_number, []]
|
73
70
|
end
|
74
|
-
|
71
|
+
|
75
72
|
# Format the number, given the national part of it.
|
76
73
|
#
|
77
|
-
def format
|
74
|
+
def format(national_number, options = {})
|
78
75
|
type = options[:format] || @format
|
79
76
|
space = options[:spaces] || @space || @@default_space
|
80
|
-
local_space = options[:local_spaces] || @local_space || space
|
77
|
+
local_space = options[:local_spaces] || @local_space || space || @@default_local_space
|
81
78
|
parentheses = options[:parentheses]
|
82
79
|
parentheses = @parentheses || @@default_parentheses if parentheses.nil?
|
83
80
|
use_trunk = options[:trunk]
|
84
|
-
|
81
|
+
|
85
82
|
trunk, ndc, *local_pieces = split national_number
|
86
|
-
|
83
|
+
|
87
84
|
local = format_local local_pieces, local_space
|
88
|
-
|
85
|
+
|
89
86
|
format_cc_ndc trunk, ndc, local, type, space, parentheses, use_trunk
|
90
87
|
end
|
91
|
-
|
88
|
+
|
89
|
+
def format_local(local, local_space)
|
92
90
|
if local.empty?
|
93
91
|
EMPTY_STRING
|
94
92
|
else
|
@@ -96,14 +94,15 @@ module Phony
|
|
96
94
|
local.join local_space.to_s
|
97
95
|
end
|
98
96
|
end
|
99
|
-
|
100
|
-
|
97
|
+
|
98
|
+
def format_cc_ndc(trunk, ndc, local, type, space, parentheses, use_trunk)
|
99
|
+
# NOTE: We mark NDCs that are of type "none" with false (nil trips plausible?). This would result in false being printed.
|
101
100
|
# Therefore we set NDC to nil when formatting.
|
102
101
|
ndc = nil if ndc == false
|
103
102
|
case type
|
104
103
|
when String
|
105
104
|
trunk &&= trunk.format(space, use_trunk)
|
106
|
-
type % { :
|
105
|
+
type % { trunk: trunk, cc: @cc, ndc: ndc, local: local }
|
107
106
|
when nil, :international_absolute, :international, :+
|
108
107
|
if ndc
|
109
108
|
format_with_ndc(@@international_absolute_format, @cc, format_ndc(ndc, parentheses), local, space)
|
@@ -121,20 +120,23 @@ module Phony
|
|
121
120
|
if ndc && !ndc.empty?
|
122
121
|
@@national_format % [trunk, format_ndc(ndc, parentheses), space, local]
|
123
122
|
else
|
124
|
-
@@national_format % [trunk, nil, nil,
|
123
|
+
@@national_format % [trunk, nil, nil, local]
|
125
124
|
end
|
126
125
|
when :local
|
127
126
|
local
|
128
127
|
end
|
129
128
|
end
|
130
|
-
|
129
|
+
|
130
|
+
def format_ndc(ndc, parentheses)
|
131
131
|
ndc = nil if ndc == false # TODO
|
132
132
|
parentheses ? "(#{ndc})" : ndc
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
|
+
def format_with_ndc(format, cc, ndc, local, space)
|
135
136
|
format % [cc, space, ndc, space, local]
|
136
137
|
end
|
137
|
-
|
138
|
+
|
139
|
+
def format_without_ndc(format, cc, local, space)
|
138
140
|
format % [cc, space, local, nil, nil]
|
139
141
|
end
|
140
142
|
|
@@ -143,12 +145,13 @@ module Phony
|
|
143
145
|
@@basic_cleaning_pattern = /\(0|\D/
|
144
146
|
# Clean number of all non-numeric characters and return a copy.
|
145
147
|
#
|
146
|
-
def clean
|
148
|
+
def clean(number)
|
147
149
|
clean! number && number.dup
|
148
150
|
end
|
151
|
+
|
149
152
|
# Clean number of all non-numeric characters and return it.
|
150
153
|
#
|
151
|
-
def clean!
|
154
|
+
def clean!(number)
|
152
155
|
number.gsub!(@@basic_cleaning_pattern, EMPTY_STRING) || number
|
153
156
|
end
|
154
157
|
|
@@ -162,21 +165,19 @@ module Phony
|
|
162
165
|
#
|
163
166
|
# Note: Options such as CC
|
164
167
|
#
|
165
|
-
def normalize
|
168
|
+
def normalize(national_number, options = {})
|
166
169
|
clean! national_number
|
167
|
-
|
170
|
+
@codes.each_with_object national_number do |code, number|
|
168
171
|
result = code.normalize number, options
|
169
172
|
break result if result
|
170
|
-
number
|
171
173
|
end
|
172
|
-
normalized
|
173
174
|
end
|
174
175
|
|
175
176
|
# Tests for plausibility of this national number.
|
176
177
|
#
|
177
|
-
def plausible?
|
178
|
+
def plausible?(rest, hints = {})
|
178
179
|
local, _, ndc, *rest = internal_split rest
|
179
|
-
|
180
|
+
|
180
181
|
# Element based checking.
|
181
182
|
#
|
182
183
|
# Note: ndc == false means the country has none.
|
@@ -193,28 +194,25 @@ module Phony
|
|
193
194
|
#
|
194
195
|
ndc_needed = hints[:ndc]
|
195
196
|
return false if ndc_needed && !(ndc_needed === ndc)
|
196
|
-
|
197
|
+
|
197
198
|
# If there is no local part, we can assume it's not a plausible number.
|
198
199
|
# (Or, not defined correctly in Phony yet)
|
199
200
|
return false unless local
|
200
201
|
|
201
202
|
# Local code specific checks.
|
202
203
|
#
|
203
|
-
|
204
|
+
local.plausible? rest, hints
|
204
205
|
end
|
205
206
|
|
206
207
|
# Is this national number a vanity number?
|
207
208
|
#
|
208
|
-
def vanity?
|
209
|
+
def vanity?(national_number)
|
209
210
|
Vanity.vanity? national_number
|
210
211
|
end
|
211
|
-
|
212
|
-
|
213
|
-
def vanity_to_number vanity_number
|
212
|
+
|
213
|
+
def vanity_to_number(vanity_number)
|
214
214
|
_, ndc, *rest = split vanity_number
|
215
215
|
"#{ndc}#{Vanity.replace(rest.join)}"
|
216
216
|
end
|
217
|
-
|
218
217
|
end
|
219
|
-
|
220
218
|
end
|
data/lib/phony/country_codes.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Phony
|
3
4
|
EMPTY_STRING = '' unless defined?(EMPTY_STRING)
|
4
5
|
|
5
6
|
# Handles determining the correct national code handler.
|
6
7
|
#
|
7
8
|
class CountryCodes
|
8
|
-
|
9
9
|
attr_reader :countries
|
10
10
|
attr_accessor :international_absolute_format, :international_relative_format, :national_format
|
11
11
|
|
@@ -14,11 +14,11 @@ module Phony
|
|
14
14
|
def self.instance
|
15
15
|
@instance ||= new
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
# Add the given country to the mapping under the
|
19
19
|
# given country code.
|
20
20
|
#
|
21
|
-
def add
|
21
|
+
def add(country_code, country)
|
22
22
|
country_code = country_code.to_s
|
23
23
|
optimized_country_code_access = country_code.size
|
24
24
|
|
@@ -29,7 +29,7 @@ module Phony
|
|
29
29
|
|
30
30
|
# Get the Country object for the given CC.
|
31
31
|
#
|
32
|
-
def []
|
32
|
+
def [](cc)
|
33
33
|
countries[cc.size][cc]
|
34
34
|
end
|
35
35
|
|
@@ -38,12 +38,13 @@ module Phony
|
|
38
38
|
@@basic_cleaning_pattern = /\A00?|\(0|\D/
|
39
39
|
# Clean number of all non-numeric characters, initial zeros or (0 and return it.
|
40
40
|
#
|
41
|
-
def clean
|
41
|
+
def clean(number)
|
42
42
|
clean! number && number.dup
|
43
43
|
end
|
44
|
+
|
44
45
|
# Clean number of all non-numeric characters, initial zeros or (0 and return a copy.
|
45
46
|
#
|
46
|
-
def clean!
|
47
|
+
def clean!(number)
|
47
48
|
number.gsub!(@@basic_cleaning_pattern, EMPTY_STRING) || number
|
48
49
|
end
|
49
50
|
|
@@ -58,33 +59,33 @@ module Phony
|
|
58
59
|
# * (0) anywhere.
|
59
60
|
# * Non-digits.
|
60
61
|
#
|
61
|
-
def normalize
|
62
|
-
country = if cc = options[:cc]
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
def normalize(number, options = {})
|
63
|
+
country = if (cc = options[:cc])
|
64
|
+
self[cc]
|
65
|
+
else
|
66
|
+
clean! number
|
67
|
+
country, cc, number = partial_split number
|
68
|
+
country
|
69
|
+
end
|
69
70
|
number = country.normalize number, cc: cc
|
70
71
|
countrify! number, cc
|
71
72
|
end
|
72
73
|
|
73
74
|
# Splits this number into cc, ndc and locally split number parts.
|
74
75
|
#
|
75
|
-
def split
|
76
|
+
def split(number)
|
76
77
|
# Split the number into country, cc, and national part.
|
77
78
|
country, cc, national_number = partial_split number
|
78
|
-
|
79
|
+
|
79
80
|
# Split the national number into ndc and local part.
|
80
81
|
_, ndc, *local = country.split national_number
|
81
|
-
|
82
|
+
|
82
83
|
[cc, ndc, *local]
|
83
84
|
end
|
84
85
|
|
85
86
|
# Format the number.
|
86
87
|
#
|
87
|
-
def format
|
88
|
+
def format(number, options = {})
|
88
89
|
country, _, national_number = partial_split number
|
89
90
|
country.format national_number, options
|
90
91
|
end
|
@@ -92,22 +93,27 @@ module Phony
|
|
92
93
|
|
93
94
|
# Is this number plausible?
|
94
95
|
#
|
95
|
-
def plausible?
|
96
|
+
def plausible?(number, hints = {})
|
97
|
+
# Fail if it contains too many of certain phone specific markers:
|
98
|
+
# * more than 1 +
|
99
|
+
#
|
100
|
+
return false if number.count('+') > 1
|
101
|
+
|
96
102
|
normalized = clean number
|
97
103
|
|
98
104
|
# False if it fails the basic check.
|
99
105
|
#
|
100
|
-
return false unless (4..16)
|
106
|
+
return false unless (4..16).include?(normalized.size) # unless hints[:check_length] == false
|
101
107
|
|
102
108
|
country, cc, rest = partial_split normalized
|
103
|
-
|
109
|
+
|
104
110
|
# Was a country calling code given?
|
105
111
|
#
|
106
|
-
if ccc = hints[:ccc]
|
112
|
+
if (ccc = hints[:ccc])
|
107
113
|
cc, ndc, *local = split ccc
|
108
|
-
|
114
|
+
|
109
115
|
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
|
-
|
116
|
+
|
111
117
|
hints[:cc] = cc
|
112
118
|
hints[:ndc] = ndc
|
113
119
|
end
|
@@ -123,55 +129,55 @@ module Phony
|
|
123
129
|
rescue ArgumentError
|
124
130
|
raise
|
125
131
|
rescue StandardError
|
126
|
-
|
132
|
+
false
|
127
133
|
end
|
128
|
-
|
134
|
+
|
129
135
|
# Is the given number a vanity number?
|
130
136
|
#
|
131
|
-
def vanity?
|
137
|
+
def vanity?(number)
|
132
138
|
country, _, national = partial_split number
|
133
139
|
country.vanity? national
|
134
140
|
end
|
141
|
+
|
135
142
|
# Converts a vanity number into a normalized E164 number.
|
136
143
|
#
|
137
|
-
def vanity_to_number
|
144
|
+
def vanity_to_number(vanity_number)
|
138
145
|
country, cc, national = partial_split vanity_number
|
139
146
|
"#{cc}#{country.vanity_to_number(national)}"
|
140
147
|
end
|
141
148
|
|
142
149
|
private
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
end
|
160
|
-
# This line is never reached as CCs are in prefix code.
|
161
|
-
end
|
162
|
-
|
163
|
-
# Adds the country code to the front
|
164
|
-
# if it does not already start with it.
|
165
|
-
#
|
166
|
-
# Note: This won't be correct in some cases, but it is the best we can do.
|
167
|
-
#
|
168
|
-
def countrify number, cc
|
169
|
-
countrify!(number, cc) || number
|
170
|
-
end
|
171
|
-
def countrify! number, cc
|
172
|
-
number.sub!(/\A/, cc) # @countrify_regex, @cc
|
150
|
+
|
151
|
+
# Return a country for the number.
|
152
|
+
#
|
153
|
+
def country_for(number)
|
154
|
+
country, = partial_split number
|
155
|
+
country
|
156
|
+
end
|
157
|
+
|
158
|
+
# Split off the country and the cc, and also return the national number part.
|
159
|
+
#
|
160
|
+
def partial_split(number)
|
161
|
+
cc = +''
|
162
|
+
1.upto(3) do |i|
|
163
|
+
cc << number.slice!(0..0)
|
164
|
+
country = countries[i][cc]
|
165
|
+
return [country, cc, number] if country
|
173
166
|
end
|
167
|
+
# This line is never reached as CCs are in prefix code.
|
168
|
+
end
|
174
169
|
|
175
|
-
|
170
|
+
# Adds the country code to the front
|
171
|
+
# if it does not already start with it.
|
172
|
+
#
|
173
|
+
# Note: This won't be correct in some cases, but it is the best we can do.
|
174
|
+
#
|
175
|
+
def countrify(number, cc)
|
176
|
+
countrify!(number, cc) || number
|
177
|
+
end
|
176
178
|
|
179
|
+
def countrify!(number, cc)
|
180
|
+
number.sub!(/\A/, cc) # @countrify_regex, @cc
|
181
|
+
end
|
182
|
+
end
|
177
183
|
end
|
data/lib/phony/dsl.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Phony
|
3
4
|
# For country definitions.
|
4
5
|
#
|
5
6
|
# There are two styles: With or without block.
|
@@ -27,7 +28,6 @@ module Phony
|
|
27
28
|
# Phony.define { ... }
|
28
29
|
#
|
29
30
|
class DSL
|
30
|
-
|
31
31
|
# Define a country's rules.
|
32
32
|
#
|
33
33
|
# Use the other DSL methods to define the country's rules.
|
@@ -40,13 +40,13 @@ module Phony
|
|
40
40
|
# @example Add a country with country code 27.
|
41
41
|
# country '27', # CC, followed by rules, for example fixed(2) >> ...
|
42
42
|
#
|
43
|
-
def country
|
43
|
+
def country(country_code, definition, options = {})
|
44
44
|
return unless Phony.config.load?(country_code)
|
45
|
-
|
45
|
+
|
46
46
|
definition.with country_code, options
|
47
47
|
Phony::CountryCodes.instance.add country_code, definition
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
# Designates a country code as reserved.
|
51
51
|
# A reserved country will result in an exception when trying to be used.
|
52
52
|
#
|
@@ -57,10 +57,10 @@ module Phony
|
|
57
57
|
# @example Designate country code 27 as reserved.
|
58
58
|
# reserved('27')
|
59
59
|
#
|
60
|
-
def reserved
|
60
|
+
def reserved(country_code)
|
61
61
|
# Does nothing, will just fail with an exception.
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
# Define a country to use default rules (and to be done at some point).
|
65
65
|
#
|
66
66
|
# @return Rules for a country.
|
@@ -71,7 +71,7 @@ module Phony
|
|
71
71
|
def todo
|
72
72
|
none >> split(10)
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
# This country uses a trunk code.
|
76
76
|
#
|
77
77
|
# @param [String] code The trunk code.
|
@@ -88,7 +88,7 @@ module Phony
|
|
88
88
|
# @example Most countries which use a trunk code use 0. E.g. Romania.
|
89
89
|
# country '40', trunk('0') | ...
|
90
90
|
#
|
91
|
-
def trunk
|
91
|
+
def trunk(code, options = {})
|
92
92
|
TrunkCode.new code, options
|
93
93
|
end
|
94
94
|
|
@@ -107,11 +107,11 @@ module Phony
|
|
107
107
|
# @example France. Uses a fixed NDC of size 1.
|
108
108
|
# country '33', fixed(1) >> split(2,2,2,2)
|
109
109
|
#
|
110
|
-
def fixed
|
110
|
+
def fixed(length, options = {})
|
111
111
|
options[:zero] = true if options[:zero].nil?
|
112
112
|
NationalSplitters::Fixed.instance_for length, options
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
# Marks the country as not using an NDC. This rule will always match.
|
116
116
|
#
|
117
117
|
# @return NationalSplitters::None A no-ndc national splitter.
|
@@ -121,7 +121,7 @@ module Phony
|
|
121
121
|
def none
|
122
122
|
NationalSplitters::None.instance_for
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
# If you have a number of (possibly) variable length NDCs
|
126
126
|
# that cannot be well expressed via regexp, use this.
|
127
127
|
#
|
@@ -135,15 +135,15 @@ module Phony
|
|
135
135
|
# one_of('103', '105') >> split(3,3)
|
136
136
|
#
|
137
137
|
def one_of *ndcs
|
138
|
-
options =
|
138
|
+
options = ndcs.last.is_a?(Hash) ? ndcs.pop : {}
|
139
139
|
|
140
140
|
# Ruby 1.8 compatibility mode.
|
141
141
|
#
|
142
|
-
ndcs = ndcs.first if
|
142
|
+
ndcs = ndcs.first if ndcs.first.is_a?(Array)
|
143
143
|
|
144
144
|
NationalSplitters::Variable.new options[:max_length], ndcs.map(&:freeze)
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
# If you have a number of (possibly) variable length NDCs
|
148
148
|
# that can be well expressed via regexp, use this.
|
149
149
|
#
|
@@ -157,11 +157,11 @@ module Phony
|
|
157
157
|
# match(/^(33|55|81)\d+$/) >> split(2,2,2,2) |
|
158
158
|
# match(/^(\d{3})\d+$/) >> split(3,2,2)
|
159
159
|
#
|
160
|
-
def match
|
160
|
+
def match(regex, options = {})
|
161
161
|
# Check if regexp has a group in it.
|
162
162
|
#
|
163
|
-
raise "Regexp /#{regex.source}/ needs a group in it that defines which digits belong to the NDC." unless regex.source
|
164
|
-
|
163
|
+
raise "Regexp /#{regex.source}/ needs a group in it that defines which digits belong to the NDC." unless /\(/.match?(regex.source)
|
164
|
+
|
165
165
|
NationalSplitters::Regex.instance_for regex, options[:on_fail_take], options
|
166
166
|
end
|
167
167
|
|
@@ -183,7 +183,7 @@ module Phony
|
|
183
183
|
# local << local.pop + 10 # Allow for call-through numbers with an arbitrary size.
|
184
184
|
LocalSplitters::Fixed.instance_for local
|
185
185
|
end
|
186
|
-
|
186
|
+
|
187
187
|
# Matches on the rest of the number and splits according
|
188
188
|
# to the given value for the regexp key.
|
189
189
|
#
|
@@ -199,18 +199,18 @@ module Phony
|
|
199
199
|
# /^[489].*$/ => [3,2,3],
|
200
200
|
# :fallback => [2,2,2,2])
|
201
201
|
#
|
202
|
-
def matched_split
|
202
|
+
def matched_split(options = {})
|
203
203
|
LocalSplitters::Regex.instance_for options
|
204
204
|
end
|
205
|
-
|
205
|
+
|
206
206
|
# Validators
|
207
207
|
#
|
208
|
-
|
208
|
+
|
209
209
|
# Which NDCs are explicitly invalid?
|
210
210
|
#
|
211
211
|
# @param [Regexp, String] ndc A regexp or a string of invalid NDCs.
|
212
212
|
#
|
213
|
-
# @return Validators::NDC An NDC validator
|
213
|
+
# @return Validators::NDC An NDC validator
|
214
214
|
#
|
215
215
|
# @example NANP
|
216
216
|
# country '1',
|
@@ -220,8 +220,5 @@ module Phony
|
|
220
220
|
def invalid_ndcs *ndc
|
221
221
|
Validators::NDC.new invalid: ndc
|
222
222
|
end
|
223
|
-
|
224
|
-
|
225
223
|
end
|
226
|
-
|
227
224
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Phony
|
2
|
-
|
3
4
|
module LocalSplitters
|
4
|
-
|
5
5
|
# Local splitter class to split the last part of
|
6
6
|
# a number, i.e. minus cc or ndc.
|
7
7
|
#
|
@@ -11,64 +11,55 @@ module Phony
|
|
11
11
|
# to avoid getting new local splitter instances.
|
12
12
|
#
|
13
13
|
class Fixed
|
14
|
-
|
15
14
|
@mapping = {}
|
16
|
-
|
15
|
+
|
17
16
|
# Get a splitter for the given format.
|
18
17
|
#
|
19
18
|
# Caches the created splitter for the given format.
|
20
19
|
#
|
21
|
-
def self.instance_for
|
20
|
+
def self.instance_for(format = nil)
|
22
21
|
@mapping[format] ||= new(format)
|
23
22
|
end
|
24
|
-
|
23
|
+
|
25
24
|
# Initialize with a local format, like [3, 2, 2] (also the default).
|
26
25
|
#
|
27
26
|
# The format [3, 2, 2] splits a number like '3332222' into ['333', '22', '22'].
|
28
27
|
#
|
29
|
-
def initialize
|
30
|
-
format = format
|
28
|
+
def initialize(format = nil)
|
29
|
+
format = format&.dup || [3, 2, 2]
|
31
30
|
@format, @length = extract_params format
|
32
31
|
@format << @format.pop + 10
|
33
32
|
end
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
def extract_params format
|
33
|
+
|
34
|
+
def extract_params(format)
|
38
35
|
if format.last.respond_to? :max
|
39
36
|
last = format.pop
|
40
|
-
length = format.
|
41
|
-
length = (length+last.min..length+last.max)
|
37
|
+
length = format.sum
|
38
|
+
length = (length + last.min..length + last.max)
|
42
39
|
format << last.min
|
43
40
|
else
|
44
|
-
length = format.
|
41
|
+
length = format.sum
|
45
42
|
end
|
46
43
|
[format, length]
|
47
44
|
end
|
48
|
-
|
45
|
+
|
49
46
|
# Split a local number according to an assumed country specific format.
|
50
47
|
#
|
51
48
|
# Examples
|
52
49
|
# * split '3643533' # => ['364', '35', '33'] # (Switzerland)
|
53
50
|
#
|
54
|
-
def split
|
55
|
-
@format.
|
56
|
-
result << number.slice!(0..size-1)
|
51
|
+
def split(number)
|
52
|
+
@format.each_with_object([]) do |size, result|
|
53
|
+
result << number.slice!(0..size - 1)
|
57
54
|
return result if number.empty?
|
58
|
-
result
|
59
55
|
end
|
60
56
|
end
|
61
|
-
|
62
|
-
|
63
|
-
#
|
64
|
-
def plausible? rest, hints = {}
|
57
|
+
|
58
|
+
def plausible?(rest, hints = {})
|
65
59
|
return true if hints[:check_length] == false
|
66
|
-
|
60
|
+
|
67
61
|
@length === rest.inject(0) { |total, part| total + part.size }
|
68
62
|
end
|
69
|
-
|
70
63
|
end
|
71
|
-
|
72
64
|
end
|
73
|
-
|
74
|
-
end
|
65
|
+
end
|