phony 1.9.0 → 2.19.14
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 +7 -0
- data/README.textile +64 -112
- data/lib/phony/config.rb +91 -0
- data/lib/phony/countries/argentina.rb +355 -0
- data/lib/phony/countries/austria.rb +56 -22
- data/lib/phony/countries/bangladesh.rb +57 -0
- data/lib/phony/countries/belarus.rb +133 -0
- data/lib/phony/countries/brazil.rb +101 -95
- data/lib/phony/countries/cambodia.rb +131 -0
- data/lib/phony/countries/china.rb +13 -6
- data/lib/phony/countries/croatia.rb +23 -0
- data/lib/phony/countries/georgia.rb +94 -0
- data/lib/phony/countries/germany.rb +66 -42
- data/lib/phony/countries/guinea.rb +46 -0
- data/lib/phony/countries/india.rb +50 -0
- data/lib/phony/countries/indonesia.rb +55 -0
- data/lib/phony/countries/ireland.rb +35 -28
- data/lib/phony/countries/italy.rb +272 -166
- data/lib/phony/countries/japan.rb +468 -0
- data/lib/phony/countries/kyrgyzstan.rb +120 -0
- data/lib/phony/countries/latvia.rb +43 -0
- data/lib/phony/countries/libya.rb +116 -0
- data/lib/phony/countries/malaysia.rb +31 -7
- data/lib/phony/countries/moldova.rb +53 -0
- data/lib/phony/countries/montenegro.rb +30 -0
- data/lib/phony/countries/myanmar.rb +55 -0
- data/lib/phony/countries/namibia.rb +37 -0
- data/lib/phony/countries/nepal.rb +73 -0
- data/lib/phony/countries/netherlands.rb +17 -5
- data/lib/phony/countries/pakistan.rb +121 -0
- data/lib/phony/countries/paraguay.rb +147 -0
- data/lib/phony/countries/{russia_kazakhstan_abhasia_south_osetia.rb → russia_kazakhstan_abkhasia_south_ossetia.rb} +35 -24
- data/lib/phony/countries/saudi_arabia.rb +40 -0
- data/lib/phony/countries/serbia.rb +47 -0
- data/lib/phony/countries/somalia.rb +26 -0
- data/lib/phony/countries/south_korea.rb +19 -10
- data/lib/phony/countries/sweden.rb +58 -38
- data/lib/phony/countries/taiwan.rb +28 -0
- data/lib/phony/countries/tajikistan.rb +79 -0
- data/lib/phony/countries/turkmenistan.rb +76 -0
- data/lib/phony/countries/ukraine.rb +630 -0
- data/lib/phony/countries/united_kingdom.rb +639 -44
- data/lib/phony/countries/uruguay.rb +53 -0
- data/lib/phony/countries/vietnam.rb +133 -0
- data/lib/phony/countries/zimbabwe.rb +39 -0
- data/lib/phony/countries.rb +901 -301
- data/lib/phony/country.rb +177 -20
- data/lib/phony/country_codes.rb +119 -101
- data/lib/phony/dsl.rb +113 -68
- data/lib/phony/local_splitters/fixed.rb +25 -1
- data/lib/phony/local_splitters/regex.rb +16 -2
- data/lib/phony/national_code.rb +7 -7
- data/lib/phony/national_splitters/default.rb +35 -3
- data/lib/phony/national_splitters/dsl.rb +12 -7
- data/lib/phony/national_splitters/fixed.rb +7 -1
- data/lib/phony/national_splitters/none.rb +7 -3
- data/lib/phony/national_splitters/regex.rb +6 -0
- data/lib/phony/national_splitters/variable.rb +13 -9
- data/lib/phony/trunk_code.rb +57 -0
- data/lib/phony/vanity.rb +3 -3
- data/lib/phony.rb +239 -55
- data/spec/functional/config_spec.rb +44 -0
- data/spec/functional/plausibility_spec.rb +656 -0
- data/spec/lib/phony/countries_spec.rb +1207 -119
- data/spec/lib/phony/country_codes_spec.rb +99 -81
- data/spec/lib/phony/country_spec.rb +54 -14
- data/spec/lib/phony/dsl_spec.rb +2 -2
- data/spec/lib/phony/local_splitters/fixed_spec.rb +4 -4
- data/spec/lib/phony/local_splitters/regex_spec.rb +50 -2
- data/spec/lib/phony/national_code_spec.rb +34 -34
- data/spec/lib/phony/national_splitters/default_spec.rb +34 -0
- data/spec/lib/phony/national_splitters/fixed_spec.rb +12 -6
- data/spec/lib/phony/national_splitters/none_spec.rb +13 -3
- data/spec/lib/phony/national_splitters/regex_spec.rb +1 -1
- data/spec/lib/phony/national_splitters/variable_spec.rb +11 -5
- data/spec/lib/phony/trunk_code_spec.rb +85 -0
- data/spec/lib/phony/vanity_spec.rb +15 -19
- data/spec/lib/phony_spec.rb +59 -277
- metadata +67 -34
- data/lib/phony/validator.rb +0 -26
- data/lib/phony/validators.rb +0 -88
- data/spec/lib/phony/validations_spec.rb +0 -109
data/lib/phony/dsl.rb
CHANGED
@@ -1,27 +1,3 @@
|
|
1
|
-
# # Switzerland (simplified):
|
2
|
-
# #
|
3
|
-
# country('41', fixed(2) >> local([3,2,2]))
|
4
|
-
#
|
5
|
-
# # Germany. Too big, we use a separate file:
|
6
|
-
# #
|
7
|
-
# Phony.define do
|
8
|
-
# country '49', match(...) >> split([...]) ||
|
9
|
-
# one_of([...], :max_length => 5) >> split([...])
|
10
|
-
# end
|
11
|
-
#
|
12
|
-
# # Denmark:
|
13
|
-
# #
|
14
|
-
# country('45', none >> split([2,2,2,2]))
|
15
|
-
#
|
16
|
-
# # Hungary:
|
17
|
-
# #
|
18
|
-
# country('36',
|
19
|
-
# match(/^104|105|107|112/) >> split([3,3]) ||
|
20
|
-
# one_of([1], :max_length => 2) >> split([3,4])
|
21
|
-
# )
|
22
|
-
#
|
23
|
-
# Note: Perhaps the DSL should operate directly on country codes.
|
24
|
-
#
|
25
1
|
module Phony
|
26
2
|
|
27
3
|
# For country definitions.
|
@@ -36,22 +12,84 @@ module Phony
|
|
36
12
|
#
|
37
13
|
# Phony.define.country ...
|
38
14
|
#
|
39
|
-
def self.define
|
15
|
+
def self.define(&block)
|
40
16
|
dsl = DSL.new
|
41
|
-
dsl.instance_eval
|
17
|
+
dsl.instance_eval(&block) if block_given?
|
42
18
|
dsl
|
43
19
|
end
|
44
20
|
|
21
|
+
# Contains a number of DSL methods. Is used e.g. in the countries.rb file.
|
22
|
+
#
|
23
|
+
# Do not use directly, but instead use {Phony.define} to execute a block
|
24
|
+
# in the DSL instance's context.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# Phony.define { ... }
|
28
|
+
#
|
45
29
|
class DSL
|
46
30
|
|
47
|
-
#
|
31
|
+
# Define a country's rules.
|
32
|
+
#
|
33
|
+
# Use the other DSL methods to define the country's rules.
|
34
|
+
#
|
35
|
+
# @param [String] country_code The country code of the country.
|
36
|
+
# @param [Phony::CountryCodes] definition Rules for this country.
|
37
|
+
#
|
38
|
+
# @return Undefined.
|
48
39
|
#
|
49
|
-
#
|
40
|
+
# @example Add a country with country code 27.
|
50
41
|
# country '27', # CC, followed by rules, for example fixed(2) >> ...
|
51
42
|
#
|
52
|
-
def country country_code,
|
53
|
-
Phony
|
54
|
-
|
43
|
+
def country country_code, definition, options = {}
|
44
|
+
return unless Phony.config.load?(country_code)
|
45
|
+
|
46
|
+
definition.with country_code, options
|
47
|
+
Phony::CountryCodes.instance.add country_code, definition
|
48
|
+
end
|
49
|
+
|
50
|
+
# Designates a country code as reserved.
|
51
|
+
# A reserved country will result in an exception when trying to be used.
|
52
|
+
#
|
53
|
+
# @param [String] country_code The country code of the country.
|
54
|
+
#
|
55
|
+
# @return nil
|
56
|
+
#
|
57
|
+
# @example Designate country code 27 as reserved.
|
58
|
+
# reserved('27')
|
59
|
+
#
|
60
|
+
def reserved country_code
|
61
|
+
# Does nothing, will just fail with an exception.
|
62
|
+
end
|
63
|
+
|
64
|
+
# Define a country to use default rules (and to be done at some point).
|
65
|
+
#
|
66
|
+
# @return Rules for a country.
|
67
|
+
#
|
68
|
+
# @example Define country 27 to use default rules.
|
69
|
+
# country '27', todo
|
70
|
+
#
|
71
|
+
def todo
|
72
|
+
none >> split(10)
|
73
|
+
end
|
74
|
+
|
75
|
+
# This country uses a trunk code.
|
76
|
+
#
|
77
|
+
# @param [String] code The trunk code.
|
78
|
+
# @param [Hash] options Options hash. Pass :normalize (true/false) to indicate whether it needs to be normalized.
|
79
|
+
#
|
80
|
+
# @return TrunkCode A trunk code handler.
|
81
|
+
#
|
82
|
+
# @example Hungary uses 06.
|
83
|
+
# country '36', trunk('06', normalize: false) | ...
|
84
|
+
#
|
85
|
+
# @example North America uses 1.
|
86
|
+
# country '1', trunk('1%s', normalize: true) | ...
|
87
|
+
#
|
88
|
+
# @example Most countries which use a trunk code use 0. E.g. Romania.
|
89
|
+
# country '40', trunk('0') | ...
|
90
|
+
#
|
91
|
+
def trunk code, options = {}
|
92
|
+
TrunkCode.new code, options
|
55
93
|
end
|
56
94
|
|
57
95
|
# National matcher & splitters.
|
@@ -61,25 +99,24 @@ module Phony
|
|
61
99
|
# uses a zero prefix when formatted
|
62
100
|
# with format :national.
|
63
101
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
# * options: Set :zero to false to not add a zero on format :national.
|
102
|
+
# @param [Fixnum] length The length of the fixed length NDC.
|
103
|
+
# @param [Hash] options An options hash (set zero: false to not add a zero on format :national).
|
67
104
|
#
|
68
|
-
#
|
69
|
-
#
|
105
|
+
# @return NationalSplitters::Fixed A fixed length national splitter.
|
106
|
+
#
|
107
|
+
# @example France. Uses a fixed NDC of size 1.
|
108
|
+
# country '33', fixed(1) >> split(2,2,2,2)
|
70
109
|
#
|
71
110
|
def fixed length, options = {}
|
72
111
|
options[:zero] = true if options[:zero].nil?
|
73
112
|
NationalSplitters::Fixed.instance_for length, options
|
74
113
|
end
|
75
114
|
|
76
|
-
#
|
115
|
+
# Marks the country as not using an NDC. This rule will always match.
|
116
|
+
#
|
117
|
+
# @return NationalSplitters::None A no-ndc national splitter.
|
77
118
|
#
|
78
|
-
#
|
79
|
-
# * Denmark
|
80
|
-
# * Norway
|
81
|
-
# * Iceland
|
82
|
-
# (and more)
|
119
|
+
# @example Denmark, Norway, Iceland.
|
83
120
|
#
|
84
121
|
def none
|
85
122
|
NationalSplitters::None.instance_for
|
@@ -88,12 +125,14 @@ module Phony
|
|
88
125
|
# If you have a number of (possibly) variable length NDCs
|
89
126
|
# that cannot be well expressed via regexp, use this.
|
90
127
|
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
128
|
+
# @param [Array<String>] ndcs A list of NDCs of variable length. Can contain :max_length => number to denote a maximum NDC length.
|
129
|
+
#
|
130
|
+
# @return NationalSplitters::Variable A variable size national splitter.
|
94
131
|
#
|
95
|
-
#
|
96
|
-
# country '51',
|
132
|
+
# @example With two NDCs
|
133
|
+
# country '51',
|
134
|
+
# # If it's either 103 or 105, then split ...
|
135
|
+
# one_of('103', '105') >> split(3,3)
|
97
136
|
#
|
98
137
|
def one_of *ndcs
|
99
138
|
options = Hash === ndcs.last ? ndcs.pop : {}
|
@@ -102,16 +141,17 @@ module Phony
|
|
102
141
|
#
|
103
142
|
ndcs = ndcs.first if Array === ndcs.first
|
104
143
|
|
105
|
-
NationalSplitters::Variable.new options[:max_length], ndcs
|
144
|
+
NationalSplitters::Variable.new options[:max_length], ndcs.map(&:freeze)
|
106
145
|
end
|
107
146
|
|
108
147
|
# If you have a number of (possibly) variable length NDCs
|
109
148
|
# that can be well expressed via regexp, use this.
|
110
149
|
#
|
111
|
-
#
|
112
|
-
# * regex A regexp describing the NDCs (First group must contain the NDC, eg. /^(0\d{2})\d+$/) contains all NDCs with 0xx...
|
150
|
+
# @param [Regexp] regex A Regexp describing the NDCs (First group must contain the NDC, eg. /^(0\d{2})\d+$/) contains all NDCs with 0xx...
|
113
151
|
#
|
114
|
-
#
|
152
|
+
# @return NationalSplitters::Regex A regexp-based national splitter.
|
153
|
+
#
|
154
|
+
# @example With several NDC matchers.
|
115
155
|
# country '52',
|
116
156
|
# match(/^(0\d{2})\d+$/) >> split(2,2,2,2) |
|
117
157
|
# match(/^(33|55|81)\d+$/) >> split(2,2,2,2) |
|
@@ -122,43 +162,45 @@ module Phony
|
|
122
162
|
#
|
123
163
|
raise "Regexp /#{regex.source}/ needs a group in it that defines which digits belong to the NDC." unless regex.source =~ /\(/
|
124
164
|
|
125
|
-
on_fail_take = options.delete :on_fail_take
|
126
165
|
NationalSplitters::Regex.instance_for regex, options[:on_fail_take], options
|
127
166
|
end
|
128
|
-
|
129
|
-
# This country still uses a default NDC (and needs to be done, hence the todo).
|
130
|
-
#
|
131
|
-
def todo
|
132
|
-
none >> NationalSplitters::Default.instance_for
|
133
|
-
end
|
134
167
|
|
135
168
|
# Local splitters.
|
136
169
|
#
|
137
170
|
|
138
171
|
# Splits the number into groups of given sizes.
|
139
172
|
#
|
140
|
-
#
|
173
|
+
# Also takes ranges.
|
174
|
+
#
|
175
|
+
# @param [Array<Fixnum>] local The local group sizes to split the local number part into.
|
176
|
+
#
|
177
|
+
# @return LocalSplitters::Fixed A fixed size local splitter.
|
178
|
+
#
|
179
|
+
# @example Splitting in 4 even groups of two digits.
|
141
180
|
# match(/^(0\d{2})\d+$/) >> split(2,2,2,2) # If it matches, split in 4 groups of size 2.
|
142
181
|
#
|
143
182
|
def split *local
|
144
|
-
local << local.pop + 10 # Allow for call-through numbers with an arbitrary size.
|
183
|
+
# local << local.pop + 10 # Allow for call-through numbers with an arbitrary size.
|
145
184
|
LocalSplitters::Fixed.instance_for local
|
146
185
|
end
|
147
186
|
|
148
187
|
# Matches on the rest of the number and splits according
|
149
188
|
# to the given value for the regexp key.
|
150
189
|
#
|
151
|
-
#
|
152
|
-
#
|
190
|
+
# Also takes ranges.
|
191
|
+
#
|
192
|
+
# @param [Hash] options Can contain option :fallback A fallback amount of group sizes in case it doesn't match.
|
193
|
+
#
|
194
|
+
# @return LocalSplitters::Regex A regexp-based local splitter.
|
153
195
|
#
|
154
|
-
#
|
196
|
+
# @example Norway
|
155
197
|
# country '47',
|
156
198
|
# none >> matched_split(/^[1].*$/ => [3],
|
157
199
|
# /^[489].*$/ => [3,2,3],
|
158
200
|
# :fallback => [2,2,2,2])
|
159
201
|
#
|
160
202
|
def matched_split options = {}
|
161
|
-
|
203
|
+
LocalSplitters::Regex.instance_for options
|
162
204
|
end
|
163
205
|
|
164
206
|
# Validators
|
@@ -166,17 +208,20 @@ module Phony
|
|
166
208
|
|
167
209
|
# Which NDCs are explicitly invalid?
|
168
210
|
#
|
169
|
-
#
|
211
|
+
# @param [Regexp, String] ndc A regexp or a string of invalid NDCs.
|
170
212
|
#
|
171
|
-
#
|
213
|
+
# @return Validators::NDC An NDC validator
|
214
|
+
#
|
215
|
+
# @example NANP
|
172
216
|
# country '1',
|
173
217
|
# fixed(3, :zero => false) >> split(3,4),
|
174
218
|
# invalid_ndcs('911') # The regexp /911/ would also work.
|
175
219
|
#
|
176
|
-
def invalid_ndcs ndc
|
177
|
-
|
220
|
+
def invalid_ndcs *ndc
|
221
|
+
Validators::NDC.new invalid: ndc
|
178
222
|
end
|
179
223
|
|
224
|
+
|
180
225
|
end
|
181
226
|
|
182
227
|
end
|
@@ -27,7 +27,23 @@ module Phony
|
|
27
27
|
# The format [3, 2, 2] splits a number like '3332222' into ['333', '22', '22'].
|
28
28
|
#
|
29
29
|
def initialize format = nil
|
30
|
-
|
30
|
+
format = format && format.dup || [3, 2, 2]
|
31
|
+
@format, @length = extract_params format
|
32
|
+
@format << @format.pop + 10
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
#
|
37
|
+
def extract_params format
|
38
|
+
if format.last.respond_to? :max
|
39
|
+
last = format.pop
|
40
|
+
length = format.inject(0) { |total, part| total + part }
|
41
|
+
length = (length+last.min..length+last.max)
|
42
|
+
format << last.min
|
43
|
+
else
|
44
|
+
length = format.inject(0) { |total, part| total + part }
|
45
|
+
end
|
46
|
+
[format, length]
|
31
47
|
end
|
32
48
|
|
33
49
|
# Split a local number according to an assumed country specific format.
|
@@ -43,6 +59,14 @@ module Phony
|
|
43
59
|
end
|
44
60
|
end
|
45
61
|
|
62
|
+
#
|
63
|
+
#
|
64
|
+
def plausible? rest, hints = {}
|
65
|
+
return true if hints[:check_length] == false
|
66
|
+
|
67
|
+
@length === rest.inject(0) { |total, part| total + part.size }
|
68
|
+
end
|
69
|
+
|
46
70
|
end
|
47
71
|
|
48
72
|
end
|
@@ -42,6 +42,15 @@ module Phony
|
|
42
42
|
split_with number, fallback
|
43
43
|
end
|
44
44
|
|
45
|
+
def plausible? rest, hints = {}
|
46
|
+
number = rest.inject('', :+)
|
47
|
+
mapping.each do |regex, format|
|
48
|
+
next unless number =~ regex
|
49
|
+
return plausible_with? number, format
|
50
|
+
end
|
51
|
+
plausible_with? number, fallback
|
52
|
+
end
|
53
|
+
|
45
54
|
private
|
46
55
|
|
47
56
|
def split_with number, format
|
@@ -49,9 +58,14 @@ module Phony
|
|
49
58
|
result << number.slice!(0..size-1)
|
50
59
|
return result if number.empty?
|
51
60
|
result
|
52
|
-
end
|
61
|
+
end << number
|
53
62
|
end
|
54
|
-
|
63
|
+
|
64
|
+
def plausible_with? number, format
|
65
|
+
length = format.inject 0, :+
|
66
|
+
number.length == length
|
67
|
+
end
|
68
|
+
|
55
69
|
end
|
56
70
|
|
57
71
|
end
|
data/lib/phony/national_code.rb
CHANGED
@@ -3,13 +3,14 @@ module Phony
|
|
3
3
|
# NationalCodes have a special numbers splitter, a national code splitter and a local code splitter.
|
4
4
|
#
|
5
5
|
class NationalCode
|
6
|
-
|
6
|
+
|
7
|
+
attr_reader :local_splitter
|
8
|
+
|
7
9
|
#
|
8
10
|
#
|
9
|
-
def initialize national_splitter, local_splitter
|
11
|
+
def initialize national_splitter, local_splitter
|
10
12
|
@national_splitter = national_splitter
|
11
13
|
@local_splitter = local_splitter
|
12
|
-
@normalize = normalize != false
|
13
14
|
end
|
14
15
|
|
15
16
|
# Split gets a number without country code and splits it into
|
@@ -25,11 +26,10 @@ module Phony
|
|
25
26
|
#
|
26
27
|
# Note: Some cases, like Italy, don't remove the relative zero.
|
27
28
|
#
|
28
|
-
def normalize national_number
|
29
|
-
|
30
|
-
national_number.gsub(/^0+/, '')
|
29
|
+
def normalize national_number, options = {}
|
30
|
+
national_number.gsub(/\A0+/, EMPTY_STRING)
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
34
34
|
|
35
|
-
end
|
35
|
+
end
|
@@ -1,15 +1,47 @@
|
|
1
1
|
module Phony
|
2
2
|
|
3
3
|
module NationalSplitters
|
4
|
-
|
4
|
+
|
5
|
+
# TODO Default = Fixed.new(...)?
|
6
|
+
#
|
5
7
|
class Default < DSL
|
6
8
|
|
7
9
|
def self.instance_for
|
8
10
|
@instance ||= new
|
9
11
|
end
|
10
|
-
|
12
|
+
|
13
|
+
# "Splits" the national part of a phone number into a single piece.
|
14
|
+
#
|
15
|
+
# @param [String] national_number An national part of a number.
|
16
|
+
#
|
17
|
+
# @return [Array<String>] An Array with the given number part as its element.
|
18
|
+
#
|
19
|
+
# @example Split the national part of a Swiss number.
|
20
|
+
# Phony.split("1234567") # => ["1234567"]
|
21
|
+
#
|
11
22
|
def split national_number
|
12
|
-
[national_number]
|
23
|
+
[nil, national_number]
|
24
|
+
end
|
25
|
+
|
26
|
+
# By default, the national part of a number is always plausible.
|
27
|
+
#
|
28
|
+
# @param [String] rest An national part of a number (ignored).
|
29
|
+
# @param [Fixnum] size Size (ignored).
|
30
|
+
# @param [Hash] hints Hints (ignored).
|
31
|
+
#
|
32
|
+
# @return [Boolean] Always true.
|
33
|
+
#
|
34
|
+
# @example Split the national part of a Swiss number.
|
35
|
+
# Phony.plausible?("1234567") # => true
|
36
|
+
#
|
37
|
+
def plausible? rest, size, hints = {}
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
# A valid length (at least 3).
|
42
|
+
#
|
43
|
+
def length
|
44
|
+
3
|
13
45
|
end
|
14
46
|
|
15
47
|
end
|
@@ -9,15 +9,20 @@ module Phony
|
|
9
9
|
#
|
10
10
|
#
|
11
11
|
def >> local_splitter
|
12
|
-
country_for local_splitter
|
12
|
+
country_for local_splitter
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
#
|
16
|
+
#
|
17
|
+
def country_for local_splitter
|
18
|
+
Phony::Country.new Phony::NationalCode.new(self, local_splitter)
|
19
|
+
end
|
20
|
+
|
21
|
+
# TODO Remove?
|
22
|
+
#
|
23
|
+
def reserved
|
24
|
+
|
25
|
+
end
|
21
26
|
|
22
27
|
end
|
23
28
|
|
@@ -20,7 +20,7 @@ module Phony
|
|
20
20
|
|
21
21
|
def initialize size, options = {}
|
22
22
|
@size = size
|
23
|
-
@zero = options[:zero] == false ? nil : '0'
|
23
|
+
@zero = nil # options[:zero] == false ? nil : '0'
|
24
24
|
end
|
25
25
|
|
26
26
|
# Takes a national number and splits it into ndc and rest.
|
@@ -30,6 +30,12 @@ module Phony
|
|
30
30
|
[@zero, national_number.slice!(0...@size), national_number]
|
31
31
|
end
|
32
32
|
|
33
|
+
# A valid length.
|
34
|
+
#
|
35
|
+
def length
|
36
|
+
@size
|
37
|
+
end
|
38
|
+
|
33
39
|
end
|
34
40
|
|
35
41
|
end
|
@@ -31,14 +31,18 @@ module Phony
|
|
31
31
|
# since using nil is dangerous and breaks
|
32
32
|
# abstraction)
|
33
33
|
#
|
34
|
-
# Note:
|
35
|
-
#
|
36
|
-
# TODO Flip nil/false?
|
34
|
+
# Note: Decided it stays in. When formatting, it's turned into nil.
|
37
35
|
#
|
38
36
|
def split national_number
|
39
37
|
[nil, false, national_number]
|
40
38
|
end
|
41
39
|
|
40
|
+
# A valid length.
|
41
|
+
#
|
42
|
+
def length
|
43
|
+
0
|
44
|
+
end
|
45
|
+
|
42
46
|
end
|
43
47
|
|
44
48
|
end
|
@@ -18,17 +18,19 @@ module Phony
|
|
18
18
|
|
19
19
|
# Extract a starting point.
|
20
20
|
#
|
21
|
+
# This if can possibly be removed.
|
22
|
+
#
|
21
23
|
presumed_code = if @mapped_ndc_min_length > 0
|
22
|
-
national_number.slice!(0..@mapped_ndc_min_length-1)
|
24
|
+
presumed_code = national_number.slice!(0..@mapped_ndc_min_length-1)
|
23
25
|
else
|
24
26
|
''
|
25
27
|
end
|
26
28
|
|
27
29
|
# Try for all possible mapped.
|
28
30
|
#
|
29
|
-
@mapped_ndc_min_length.upto
|
30
|
-
|
31
|
-
return [@zero, presumed_code, national_number] unless
|
31
|
+
@mapped_ndc_min_length.upto @mapped_ndc_max_length do |i|
|
32
|
+
ndcs_of_size_i = @ndcs[i]
|
33
|
+
return [@zero, presumed_code, national_number] unless ndcs_of_size_i && !ndcs_of_size_i.include?(presumed_code)
|
32
34
|
presumed_code << national_number.slice!(0..0)
|
33
35
|
end
|
34
36
|
|
@@ -37,15 +39,17 @@ module Phony
|
|
37
39
|
super fallback_number
|
38
40
|
end
|
39
41
|
|
42
|
+
# A valid length.
|
43
|
+
#
|
44
|
+
def length
|
45
|
+
(@mapped_ndc_min_length..@mapped_ndc_max_length)
|
46
|
+
end
|
47
|
+
|
40
48
|
private
|
41
49
|
|
42
|
-
# def restructure ndc_map
|
43
|
-
# optimize ndc_map.values.flatten
|
44
|
-
# end
|
45
|
-
|
46
50
|
# Optimizes and restructures the given ndcs array.
|
47
51
|
#
|
48
|
-
def optimize
|
52
|
+
def optimize ndc_ary
|
49
53
|
ndcs = {}
|
50
54
|
ndc_ary.each do |ndc|
|
51
55
|
ndcs[ndc.length] ||= []
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Phony
|
2
|
+
|
3
|
+
class TrunkCode
|
4
|
+
|
5
|
+
# Parameters:
|
6
|
+
# * code: The trunk code, e.g. 0.
|
7
|
+
#
|
8
|
+
# Options:
|
9
|
+
# * normalize: [true (default), false] Remove the trunk code when normalizing (only use if number scheme is defined unambiguously).
|
10
|
+
# * split: [true, false (default)] Remove the trunk code when splitting (only use if number scheme is defined unambiguously).
|
11
|
+
# * format: [true (default), false] Add the trunk code when formatting (passing `false` will not add it).
|
12
|
+
#
|
13
|
+
def initialize code, options = {}
|
14
|
+
@code = code
|
15
|
+
@trunk_code_replacement = /\A#{code.gsub(%r{%s}, '')}/
|
16
|
+
@normalize = options[:normalize] || options[:normalize].nil?
|
17
|
+
@split = options[:split]
|
18
|
+
@format = options[:format] || options[:format].nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Prepends itself to the other codes.
|
22
|
+
#
|
23
|
+
def | other
|
24
|
+
other.codes.unshift self
|
25
|
+
other
|
26
|
+
end
|
27
|
+
|
28
|
+
# Split gets a number without country code and splits it into
|
29
|
+
# its parts.
|
30
|
+
#
|
31
|
+
def split national_number
|
32
|
+
national_number.gsub! @trunk_code_replacement, EMPTY_STRING if @split
|
33
|
+
return [self, national_number]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Normalize normalizes the given national number.
|
37
|
+
#
|
38
|
+
def normalize national_number, options = {}
|
39
|
+
national_number.gsub! @trunk_code_replacement, EMPTY_STRING if @normalize && options[:cc]
|
40
|
+
return national_number
|
41
|
+
end
|
42
|
+
|
43
|
+
# Format the trunk code using the spaces given.
|
44
|
+
#
|
45
|
+
def format space, force = nil
|
46
|
+
if force || @format
|
47
|
+
if @code.size > 1
|
48
|
+
(@code % space).gsub(/\D/, ' ')
|
49
|
+
else
|
50
|
+
@code
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/phony/vanity.rb
CHANGED
@@ -16,11 +16,11 @@ module Phony
|
|
16
16
|
# Replaces (and normalizes) vanity characters of passed number with correct digits.
|
17
17
|
#
|
18
18
|
def self.replace number
|
19
|
-
number.tr
|
19
|
+
number.tr(*mapping)
|
20
20
|
end
|
21
21
|
|
22
22
|
# Returns true if there is a character in the number
|
23
|
-
# after the first
|
23
|
+
# after the first three numbers.
|
24
24
|
#
|
25
25
|
@@vanity_regexp = /\A\d{3}[a-zA-Z]{6,12}\Z/
|
26
26
|
def self.vanity? number
|
@@ -29,7 +29,7 @@ module Phony
|
|
29
29
|
|
30
30
|
# Vanity-Normalized.
|
31
31
|
#
|
32
|
-
@@vanity_normalizing_regexp = /^0*|[^\
|
32
|
+
@@vanity_normalizing_regexp = /^0*|[^\w]/
|
33
33
|
def self.normalized number
|
34
34
|
number.gsub @@vanity_normalizing_regexp, ''
|
35
35
|
end
|