mini_phone 1.0.1 → 1.0.6
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.md +17 -15
- data/Rakefile +13 -8
- data/ext/mini_phone/mini_phone.cc +189 -39
- data/lib/mini_phone/version.rb +1 -1
- data/mini_phone.gemspec +4 -1
- metadata +2 -9
- data/.clang-format +0 -3
- data/.github/workflows/ci.yml +0 -51
- data/.github/workflows/release.yml +0 -47
- data/.gitignore +0 -19
- data/.rspec +0 -3
- data/.rubocop.yml +0 -23
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f7c87533de0643b9af5d9394d62a238208c34fa34e16effbb9064e9fd3578d7
|
4
|
+
data.tar.gz: 5868d8b76184925da0ba875fa0a5df7c3bb61f920b51f5d9391fd2d742335ddc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bdb02eee2405855e49defd3e27d9eccd8934ec1bc1c02977b69d17026d32500969b443b053b1eece4ca7f72294a2d57349c19cfe14f6993c02dab6d21ec9d21
|
7
|
+
data.tar.gz: e57f59c8c2b75a1e4983d8a7fc3941fa1c641bd1c55eb13185bc9c8b35347b39a3ce301e65e021887f5bfc403ee8b0b5e5bad60d20e3604900418c0b6d46511e
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# MiniPhone
|
2
2
|
|
3
|
-
A Ruby gem which plugs directly
|
4
|
-
[libphonenumber](https://github.com/google/libphonenumber) for
|
3
|
+
A Ruby gem which plugs directly into Google's native C++
|
4
|
+
[libphonenumber](https://github.com/google/libphonenumber) for extremely
|
5
5
|
_fast_ and _robust_ phone number parsing, validation, and formatting. On
|
6
|
-
average, most methods are 40x
|
6
|
+
average, most methods are 40x to 50x faster than other Ruby phone number
|
7
7
|
libraries.
|
8
8
|
|
9
9
|
## Usage
|
@@ -23,10 +23,12 @@ MiniPhone.default_country = 'US'
|
|
23
23
|
|
24
24
|
phone_number = MiniPhone.parse('404-384-1399')
|
25
25
|
|
26
|
-
phone_number.e164
|
27
|
-
phone_number.national
|
28
|
-
phone_number.
|
29
|
-
phone_number.
|
26
|
+
phone_number.e164 # +14043841399
|
27
|
+
phone_number.national # (404) 384-1399
|
28
|
+
phone_number.raw_national # 4043841399
|
29
|
+
phone_number.dasherized_national # 404-384-1399
|
30
|
+
phone_number.international # +1 404-384-1399
|
31
|
+
phone_number.rfc3966 # tel:+1-404-384-1384
|
30
32
|
```
|
31
33
|
|
32
34
|
### Checking if a phone number is possible
|
@@ -41,7 +43,7 @@ phone_number.possible? # false
|
|
41
43
|
|
42
44
|
```ruby
|
43
45
|
MiniPhone.parse('+12423570000').type # :mobile
|
44
|
-
MiniPhone.parse
|
46
|
+
MiniPhone.parse('+12423651234').type # :fixed_line
|
45
47
|
```
|
46
48
|
|
47
49
|
The possible types are directly mapped from [this
|
@@ -65,14 +67,14 @@ enum](https://github.com/google/libphonenumber/blob/4e9954edea7cf263532c5dd3861a
|
|
65
67
|
## Compatibility with PhoneLib
|
66
68
|
|
67
69
|
MiniPhone aims to be compatible with
|
68
|
-
[Phonelib](https://github.com/daddyz/phonelib)
|
69
|
-
drop in replacement. It has a smaller feature set, so
|
70
|
-
|
70
|
+
[Phonelib](https://github.com/daddyz/phonelib). In many cases it can be a
|
71
|
+
drop in replacement. It has a smaller feature set, so it is not a
|
72
|
+
replacement for every use case. If there is a feature you need, open
|
71
73
|
an issue and we will try to support it.
|
72
74
|
|
73
75
|
## Benchmarks
|
74
76
|
|
75
|
-
On average, most methods are 40x
|
77
|
+
On average, most methods are 40x to 50x faster than other libraries. To run
|
76
78
|
the benchmarks locally, execute: `bundle exec rake bench`
|
77
79
|
|
78
80
|
```
|
@@ -132,10 +134,10 @@ push git commits and tags, and push the `.gem` file to
|
|
132
134
|
## Contributing
|
133
135
|
|
134
136
|
Bug reports and pull requests are welcome on GitHub at
|
135
|
-
https://github.com/
|
137
|
+
https://github.com/ianks/mini_phone. This project is intended to be a
|
136
138
|
safe, welcoming space for collaboration, and contributors are expected to
|
137
139
|
adhere to the [code of
|
138
|
-
conduct](https://github.com/
|
140
|
+
conduct](https://github.com/ianks/mini_phone/blob/master/CODE_OF_CONDUCT.md).
|
139
141
|
|
140
142
|
## License
|
141
143
|
|
@@ -146,4 +148,4 @@ License](https://opensource.org/licenses/MIT).
|
|
146
148
|
|
147
149
|
Everyone interacting in the MiniPhone project's codebases, issue trackers,
|
148
150
|
chat rooms and mailing lists is expected to follow the [code of
|
149
|
-
conduct](https://github.com/
|
151
|
+
conduct](https://github.com/ianks/mini_phone/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ RSpec::Core::RakeTask.new(:spec)
|
|
9
9
|
|
10
10
|
task build: :compile
|
11
11
|
|
12
|
-
task default: %i[clobber compile spec]
|
12
|
+
task default: %i[clobber compile spec lint]
|
13
13
|
|
14
14
|
spec = Gem::Specification.load(File.expand_path('mini_phone.gemspec', __dir__))
|
15
15
|
|
@@ -28,7 +28,16 @@ task bench: %i[clobber compile] do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
task :
|
31
|
+
task :lint do
|
32
|
+
sh 'bundle exec rubocop'
|
33
|
+
end
|
34
|
+
|
35
|
+
task :format do
|
36
|
+
sh 'bundle exec rubocop -A'
|
37
|
+
sh 'clang-format -i ext/**/*.{h,cc}'
|
38
|
+
end
|
39
|
+
|
40
|
+
task deploy: :default do
|
32
41
|
sh 'code -w ./lib/mini_phone/version.rb'
|
33
42
|
version = `ruby -r ./lib/mini_phone/version.rb -e 'print MiniPhone::VERSION'`.strip
|
34
43
|
sh "git commit -am 'Bump to v#{version} :confetti_ball:'"
|
@@ -63,11 +72,7 @@ namespace :publish do
|
|
63
72
|
task non_native: [:gem] do
|
64
73
|
g = "./pkg/mini_phone-#{MiniPhone::VERSION}.gem"
|
65
74
|
|
66
|
-
|
67
|
-
|
68
|
-
results << push_to_rubygems(g)
|
69
|
-
results << push_to_github_registry(g)
|
70
|
-
|
71
|
-
abort if results.all? { |r| r == true }
|
75
|
+
push_to_rubygems(g)
|
76
|
+
push_to_github_registry(g)
|
72
77
|
end
|
73
78
|
end
|
@@ -1,12 +1,19 @@
|
|
1
1
|
#include "mini_phone.h"
|
2
|
+
#include "phonenumbers/phonemetadata.pb.h"
|
3
|
+
#include "phonenumbers/phonenumber.pb.h"
|
2
4
|
#include "phonenumbers/phonenumberutil.h"
|
3
5
|
|
4
6
|
using namespace ::i18n::phonenumbers;
|
5
7
|
|
8
|
+
using google::protobuf::RepeatedPtrField;
|
9
|
+
|
6
10
|
static VALUE rb_mMiniPhone;
|
7
11
|
|
8
12
|
static VALUE rb_cPhoneNumber;
|
9
13
|
|
14
|
+
static RepeatedPtrField<NumberFormat> raw_national_format;
|
15
|
+
static RepeatedPtrField<NumberFormat> dasherized_national_format;
|
16
|
+
|
10
17
|
extern "C" struct PhoneNumberInfo {
|
11
18
|
PhoneNumber phone_number;
|
12
19
|
std::string raw_phone_number;
|
@@ -14,15 +21,19 @@ extern "C" struct PhoneNumberInfo {
|
|
14
21
|
};
|
15
22
|
|
16
23
|
static inline VALUE is_phone_number_valid(VALUE self, VALUE str, VALUE cc) {
|
24
|
+
if (NIL_P(str) || NIL_P(cc)) {
|
25
|
+
return Qfalse;
|
26
|
+
}
|
27
|
+
|
17
28
|
PhoneNumber parsed_number;
|
18
|
-
PhoneNumberUtil *
|
29
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
19
30
|
|
20
31
|
std::string phone_number(RSTRING_PTR(str), RSTRING_LEN(str));
|
21
32
|
std::string country_code(RSTRING_PTR(cc), RSTRING_LEN(cc));
|
22
33
|
|
23
|
-
auto result = phone_util
|
34
|
+
auto result = phone_util.ParseAndKeepRawInput(phone_number, country_code, &parsed_number);
|
24
35
|
|
25
|
-
if (result == PhoneNumberUtil::NO_PARSING_ERROR && phone_util
|
36
|
+
if (result == PhoneNumberUtil::NO_PARSING_ERROR && phone_util.IsValidNumber(parsed_number)) {
|
26
37
|
return Qtrue;
|
27
38
|
} else {
|
28
39
|
return Qfalse;
|
@@ -35,6 +46,20 @@ extern "C" VALUE rb_is_phone_number_valid(VALUE self, VALUE str) {
|
|
35
46
|
return is_phone_number_valid(self, str, def_cc);
|
36
47
|
}
|
37
48
|
|
49
|
+
extern "C" VALUE rb_normalize_digits_only(VALUE self, VALUE str) {
|
50
|
+
if (NIL_P(str)) {
|
51
|
+
return Qnil;
|
52
|
+
}
|
53
|
+
|
54
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
55
|
+
|
56
|
+
std::string phone_number(RSTRING_PTR(str), RSTRING_LEN(str));
|
57
|
+
|
58
|
+
phone_util.NormalizeDigitsOnly(&phone_number);
|
59
|
+
|
60
|
+
return rb_str_new(phone_number.c_str(), phone_number.size());
|
61
|
+
}
|
62
|
+
|
38
63
|
extern "C" VALUE rb_is_phone_number_valid_for_country(VALUE self, VALUE str, VALUE cc) {
|
39
64
|
return is_phone_number_valid(self, str, cc);
|
40
65
|
}
|
@@ -48,16 +73,20 @@ extern "C" VALUE rb_is_phone_number_invalid_for_country(VALUE self, VALUE str, V
|
|
48
73
|
}
|
49
74
|
|
50
75
|
extern "C" VALUE rb_is_phone_number_possible(VALUE self, VALUE str) {
|
76
|
+
if (NIL_P(str)) {
|
77
|
+
return Qnil;
|
78
|
+
}
|
79
|
+
|
51
80
|
PhoneNumber parsed_number;
|
52
|
-
PhoneNumberUtil *
|
81
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
53
82
|
|
54
83
|
VALUE def_cc = rb_iv_get(rb_mMiniPhone, "@default_country");
|
55
84
|
std::string phone_number(RSTRING_PTR(str), RSTRING_LEN(str));
|
56
85
|
std::string country_code(RSTRING_PTR(def_cc), RSTRING_LEN(def_cc));
|
57
86
|
|
58
|
-
auto result = phone_util
|
87
|
+
auto result = phone_util.Parse(phone_number, country_code, &parsed_number);
|
59
88
|
|
60
|
-
if (result == PhoneNumberUtil::NO_PARSING_ERROR && phone_util
|
89
|
+
if (result == PhoneNumberUtil::NO_PARSING_ERROR && phone_util.IsPossibleNumber(parsed_number)) {
|
61
90
|
return Qtrue;
|
62
91
|
} else {
|
63
92
|
return Qfalse;
|
@@ -69,6 +98,10 @@ extern "C" VALUE rb_is_phone_number_impossible(VALUE self, VALUE str) {
|
|
69
98
|
}
|
70
99
|
|
71
100
|
extern "C" VALUE rb_set_default_country(VALUE self, VALUE str_code) {
|
101
|
+
if (NIL_P(str_code)) {
|
102
|
+
str_code = rb_str_new("ZZ", 2);
|
103
|
+
}
|
104
|
+
|
72
105
|
return rb_iv_set(self, "@default_country", str_code);
|
73
106
|
}
|
74
107
|
|
@@ -89,7 +122,11 @@ extern "C" VALUE rb_phone_number_alloc(VALUE self) {
|
|
89
122
|
|
90
123
|
static inline VALUE rb_phone_number_nullify_ivars(VALUE self) {
|
91
124
|
rb_iv_set(self, "@national", Qnil);
|
125
|
+
rb_iv_set(self, "@raw_national", Qnil);
|
126
|
+
rb_iv_set(self, "@dasherized_national", Qnil);
|
92
127
|
rb_iv_set(self, "@international", Qnil);
|
128
|
+
rb_iv_set(self, "@raw_international", Qnil);
|
129
|
+
rb_iv_set(self, "@dasherized_international", Qnil);
|
93
130
|
rb_iv_set(self, "@e164", Qnil);
|
94
131
|
rb_iv_set(self, "@country_code", Qnil);
|
95
132
|
rb_iv_set(self, "@region_code", Qnil);
|
@@ -97,6 +134,7 @@ static inline VALUE rb_phone_number_nullify_ivars(VALUE self) {
|
|
97
134
|
rb_iv_set(self, "@type", Qnil);
|
98
135
|
rb_iv_set(self, "@valid", Qfalse);
|
99
136
|
rb_iv_set(self, "@possible", Qfalse);
|
137
|
+
rb_iv_set(self, "@area_code", Qnil);
|
100
138
|
|
101
139
|
return Qtrue;
|
102
140
|
}
|
@@ -124,12 +162,12 @@ extern "C" VALUE rb_phone_number_initialize(int argc, VALUE *argv, VALUE self) {
|
|
124
162
|
|
125
163
|
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
126
164
|
|
127
|
-
PhoneNumberUtil *
|
165
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
128
166
|
|
129
167
|
std::string phone_number(RSTRING_PTR(str), RSTRING_LEN(str));
|
130
168
|
std::string country_code(RSTRING_PTR(def_cc), RSTRING_LEN(def_cc));
|
131
169
|
|
132
|
-
auto result = phone_util
|
170
|
+
auto result = phone_util.Parse(phone_number, country_code, &parsed_number);
|
133
171
|
|
134
172
|
if (result != PhoneNumberUtil::NO_PARSING_ERROR) {
|
135
173
|
rb_phone_number_nullify_ivars(self);
|
@@ -145,9 +183,9 @@ static inline VALUE rb_phone_number_format(VALUE self, PhoneNumberUtil::PhoneNum
|
|
145
183
|
PhoneNumberInfo *phone_number_info;
|
146
184
|
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
147
185
|
|
148
|
-
PhoneNumberUtil *
|
186
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
149
187
|
PhoneNumber parsed_number = phone_number_info->phone_number;
|
150
|
-
phone_util
|
188
|
+
phone_util.Format(parsed_number, fmt, &formatted_number);
|
151
189
|
|
152
190
|
return rb_str_new(formatted_number.c_str(), formatted_number.size());
|
153
191
|
}
|
@@ -185,6 +223,78 @@ extern "C" VALUE rb_phone_number_rfc3966(VALUE self) {
|
|
185
223
|
return rb_iv_set(self, "@rfc3966", rb_phone_number_format(self, PhoneNumberUtil::PhoneNumberFormat::RFC3966));
|
186
224
|
}
|
187
225
|
|
226
|
+
VALUE format_by_pattern_national(VALUE self, RepeatedPtrField<NumberFormat> format) {
|
227
|
+
std::string formatted_number;
|
228
|
+
PhoneNumberInfo *phone_number_info;
|
229
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
230
|
+
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
231
|
+
|
232
|
+
phone_util.FormatByPattern(phone_number_info->phone_number, PhoneNumberUtil::NATIONAL, format, &formatted_number);
|
233
|
+
|
234
|
+
return rb_str_new(formatted_number.c_str(), formatted_number.size());
|
235
|
+
}
|
236
|
+
|
237
|
+
extern "C" VALUE rb_phone_number_raw_national(VALUE self) {
|
238
|
+
if (rb_ivar_defined(self, rb_intern("@raw_national"))) {
|
239
|
+
return rb_iv_get(self, "@raw_national");
|
240
|
+
}
|
241
|
+
|
242
|
+
VALUE result = format_by_pattern_national(self, raw_national_format);
|
243
|
+
|
244
|
+
return rb_iv_set(self, "@raw_national", result);
|
245
|
+
}
|
246
|
+
|
247
|
+
extern "C" VALUE rb_phone_number_dasherized_national(VALUE self) {
|
248
|
+
if (rb_ivar_defined(self, rb_intern("@dasherized_national"))) {
|
249
|
+
return rb_iv_get(self, "@dasherized_national");
|
250
|
+
}
|
251
|
+
|
252
|
+
VALUE result = format_by_pattern_national(self, dasherized_national_format);
|
253
|
+
|
254
|
+
return rb_iv_set(self, "@dasherized_national", result);
|
255
|
+
}
|
256
|
+
|
257
|
+
extern "C" VALUE rb_phone_number_country_code(VALUE self) {
|
258
|
+
if (rb_ivar_defined(self, rb_intern("@country_code"))) {
|
259
|
+
return rb_iv_get(self, "@country_code");
|
260
|
+
}
|
261
|
+
|
262
|
+
PhoneNumberInfo *phone_number_info;
|
263
|
+
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
264
|
+
|
265
|
+
int code = phone_number_info->phone_number.country_code();
|
266
|
+
|
267
|
+
VALUE result = INT2NUM(code);
|
268
|
+
|
269
|
+
return rb_iv_set(self, "@country_code", result);
|
270
|
+
}
|
271
|
+
|
272
|
+
extern "C" VALUE rb_phone_number_dasherized_international(VALUE self) {
|
273
|
+
if (rb_ivar_defined(self, rb_intern("@dasherized_international"))) {
|
274
|
+
return rb_iv_get(self, "@dasherized_international");
|
275
|
+
}
|
276
|
+
|
277
|
+
VALUE national = rb_phone_number_dasherized_national(self);
|
278
|
+
VALUE cc = rb_fix2str(rb_phone_number_country_code(self), 10);
|
279
|
+
VALUE dash = rb_str_new("-", 1);
|
280
|
+
VALUE prefix = rb_str_concat(cc, dash);
|
281
|
+
VALUE result = rb_str_concat(prefix, national);
|
282
|
+
|
283
|
+
return rb_iv_set(self, "@dasherized_international", result);
|
284
|
+
}
|
285
|
+
|
286
|
+
extern "C" VALUE rb_phone_number_raw_international(VALUE self) {
|
287
|
+
if (rb_ivar_defined(self, rb_intern("@raw_international"))) {
|
288
|
+
return rb_iv_get(self, "@raw_international");
|
289
|
+
}
|
290
|
+
|
291
|
+
VALUE national = rb_phone_number_raw_national(self);
|
292
|
+
VALUE cc = rb_fix2str(rb_phone_number_country_code(self), 10);
|
293
|
+
VALUE result = rb_str_concat(cc, national);
|
294
|
+
|
295
|
+
return rb_iv_set(self, "@raw_international", result);
|
296
|
+
}
|
297
|
+
|
188
298
|
extern "C" VALUE rb_phone_number_valid_eh(VALUE self) {
|
189
299
|
if (rb_ivar_defined(self, rb_intern("@valid"))) {
|
190
300
|
return rb_iv_get(self, "@valid");
|
@@ -194,9 +304,9 @@ extern "C" VALUE rb_phone_number_valid_eh(VALUE self) {
|
|
194
304
|
PhoneNumberInfo *phone_number_info;
|
195
305
|
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
196
306
|
|
197
|
-
PhoneNumberUtil *
|
307
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
198
308
|
|
199
|
-
if (phone_util
|
309
|
+
if (phone_util.IsValidNumber(phone_number_info->phone_number)) {
|
200
310
|
return rb_iv_set(self, "@valid", Qtrue);
|
201
311
|
} else {
|
202
312
|
return rb_iv_set(self, "@valid", Qfalse);
|
@@ -216,9 +326,9 @@ extern "C" VALUE rb_phone_number_possible_eh(VALUE self) {
|
|
216
326
|
PhoneNumberInfo *phone_number_info;
|
217
327
|
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
218
328
|
|
219
|
-
PhoneNumberUtil *
|
329
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
220
330
|
|
221
|
-
if (phone_util
|
331
|
+
if (phone_util.IsPossibleNumber(phone_number_info->phone_number)) {
|
222
332
|
return rb_iv_set(self, "@possible", Qtrue);
|
223
333
|
} else {
|
224
334
|
return rb_iv_set(self, "@possible", Qfalse);
|
@@ -237,43 +347,28 @@ extern "C" VALUE rb_phone_number_region_code(VALUE self) {
|
|
237
347
|
PhoneNumberInfo *phone_number_info;
|
238
348
|
std::string code;
|
239
349
|
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
240
|
-
PhoneNumberUtil *
|
350
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
241
351
|
|
242
|
-
phone_util
|
352
|
+
phone_util.GetRegionCodeForCountryCode(phone_number_info->phone_number.country_code(), &code);
|
243
353
|
|
244
354
|
VALUE result = rb_str_new(code.c_str(), code.size());
|
245
355
|
|
246
356
|
return rb_iv_set(self, "@region_code", result);
|
247
357
|
}
|
248
358
|
|
249
|
-
extern "C" VALUE rb_phone_number_country_code(VALUE self) {
|
250
|
-
if (rb_ivar_defined(self, rb_intern("@country_code"))) {
|
251
|
-
return rb_iv_get(self, "@country_code");
|
252
|
-
}
|
253
|
-
|
254
|
-
PhoneNumberInfo *phone_number_info;
|
255
|
-
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
256
|
-
|
257
|
-
int code = phone_number_info->phone_number.country_code();
|
258
|
-
|
259
|
-
VALUE result = INT2NUM(code);
|
260
|
-
|
261
|
-
return rb_iv_set(self, "@country_code", result);
|
262
|
-
}
|
263
|
-
|
264
359
|
extern "C" VALUE rb_phone_number_eql_eh(VALUE self, VALUE other) {
|
265
360
|
if (!rb_obj_is_instance_of(other, rb_cPhoneNumber)) {
|
266
361
|
return Qfalse;
|
267
362
|
}
|
268
363
|
|
269
|
-
PhoneNumberUtil *
|
364
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
270
365
|
|
271
366
|
PhoneNumberInfo *self_phone_number_info;
|
272
367
|
Data_Get_Struct(self, PhoneNumberInfo, self_phone_number_info);
|
273
368
|
|
274
369
|
PhoneNumberInfo *other_phone_number_info;
|
275
370
|
Data_Get_Struct(other, PhoneNumberInfo, other_phone_number_info);
|
276
|
-
if (phone_util
|
371
|
+
if (phone_util.IsNumberMatch(other_phone_number_info->phone_number, self_phone_number_info->phone_number)) {
|
277
372
|
return Qtrue;
|
278
373
|
} else {
|
279
374
|
return Qfalse;
|
@@ -287,13 +382,13 @@ extern "C" VALUE rb_phone_number_type(VALUE self) {
|
|
287
382
|
|
288
383
|
PhoneNumberInfo *phone_number_info;
|
289
384
|
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
290
|
-
PhoneNumberUtil *
|
385
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
291
386
|
|
292
387
|
VALUE result;
|
293
388
|
|
294
389
|
// @see
|
295
390
|
// https://github.com/google/libphonenumber/blob/4e9954edea7cf263532c5dd3861a801104c3f012/cpp/src/phonenumbers/phonenumberutil.h#L91
|
296
|
-
switch (phone_util
|
391
|
+
switch (phone_util.GetNumberType(phone_number_info->phone_number)) {
|
297
392
|
case PhoneNumberUtil::PREMIUM_RATE:
|
298
393
|
result = rb_intern("premium_rate");
|
299
394
|
break;
|
@@ -335,7 +430,50 @@ extern "C" VALUE rb_phone_number_type(VALUE self) {
|
|
335
430
|
return rb_iv_set(self, "@type", ID2SYM(result));
|
336
431
|
}
|
337
432
|
|
433
|
+
extern "C" VALUE rb_phone_number_area_code(VALUE self) {
|
434
|
+
if (rb_ivar_defined(self, rb_intern("@area_code"))) {
|
435
|
+
return rb_iv_get(self, "@area_code");
|
436
|
+
}
|
437
|
+
|
438
|
+
const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
|
439
|
+
PhoneNumberInfo *phone_number_info;
|
440
|
+
Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
|
441
|
+
|
442
|
+
PhoneNumber number = phone_number_info->phone_number;
|
443
|
+
string national_significant_number;
|
444
|
+
phone_util.GetNationalSignificantNumber(number, &national_significant_number);
|
445
|
+
string area_code;
|
446
|
+
string subscriber_number;
|
447
|
+
|
448
|
+
int area_code_length = phone_util.GetLengthOfGeographicalAreaCode(number);
|
449
|
+
if (area_code_length > 0) {
|
450
|
+
area_code = national_significant_number.substr(0, area_code_length);
|
451
|
+
subscriber_number = national_significant_number.substr(area_code_length, string::npos);
|
452
|
+
} else {
|
453
|
+
area_code = "";
|
454
|
+
subscriber_number = national_significant_number;
|
455
|
+
}
|
456
|
+
|
457
|
+
VALUE result = rb_str_new(area_code.c_str(), area_code.size());
|
458
|
+
|
459
|
+
return rb_iv_set(self, "@area_code", result);
|
460
|
+
}
|
461
|
+
|
462
|
+
static inline void setup_formats() {
|
463
|
+
// Raw
|
464
|
+
NumberFormat *raw_fmt = raw_national_format.Add();
|
465
|
+
raw_fmt->set_pattern("(\\d{3})(\\d{3})(\\d{4})");
|
466
|
+
raw_fmt->set_format("$1$2$3");
|
467
|
+
|
468
|
+
// Dasherized
|
469
|
+
NumberFormat *dsh_fmt = dasherized_national_format.Add();
|
470
|
+
dsh_fmt->set_pattern("(\\d{3})(\\d{3})(\\d{4})");
|
471
|
+
dsh_fmt->set_format("$1-$2-$3");
|
472
|
+
}
|
473
|
+
|
338
474
|
extern "C" void Init_mini_phone(void) {
|
475
|
+
setup_formats();
|
476
|
+
|
339
477
|
rb_mMiniPhone = rb_define_module("MiniPhone");
|
340
478
|
|
341
479
|
// Unknown
|
@@ -350,11 +488,13 @@ extern "C" void Init_mini_phone(void) {
|
|
350
488
|
rb_define_module_function(rb_mMiniPhone, "possible?", reinterpret_cast<VALUE (*)(...)>(rb_is_phone_number_valid), 1);
|
351
489
|
rb_define_module_function(rb_mMiniPhone, "impossible?", reinterpret_cast<VALUE (*)(...)>(rb_is_phone_number_invalid),
|
352
490
|
1);
|
353
|
-
rb_define_module_function(rb_mMiniPhone,
|
354
|
-
|
355
|
-
rb_define_module_function(rb_mMiniPhone, "default_country",
|
356
|
-
|
491
|
+
rb_define_module_function(rb_mMiniPhone, "default_country=", reinterpret_cast<VALUE (*)(...)>(rb_set_default_country),
|
492
|
+
1);
|
493
|
+
rb_define_module_function(rb_mMiniPhone, "default_country", reinterpret_cast<VALUE (*)(...)>(rb_get_default_country),
|
494
|
+
0);
|
357
495
|
rb_define_module_function(rb_mMiniPhone, "parse", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_parse), -1);
|
496
|
+
rb_define_module_function(rb_mMiniPhone, "normalize_digits_only",
|
497
|
+
reinterpret_cast<VALUE (*)(...)>(rb_normalize_digits_only), 1);
|
358
498
|
|
359
499
|
rb_cPhoneNumber = rb_define_class_under(rb_mMiniPhone, "PhoneNumber", rb_cObject);
|
360
500
|
|
@@ -367,11 +507,21 @@ extern "C" void Init_mini_phone(void) {
|
|
367
507
|
rb_define_method(rb_cPhoneNumber, "impossible?", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_impossible_eh), 0);
|
368
508
|
rb_define_method(rb_cPhoneNumber, "e164", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_e164), 0);
|
369
509
|
rb_define_method(rb_cPhoneNumber, "national", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_national), 0);
|
510
|
+
|
511
|
+
rb_define_method(rb_cPhoneNumber, "raw_national", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_raw_national), 0);
|
512
|
+
rb_define_method(rb_cPhoneNumber, "raw_international",
|
513
|
+
reinterpret_cast<VALUE (*)(...)>(rb_phone_number_raw_international), 0);
|
514
|
+
rb_define_method(rb_cPhoneNumber, "dasherized_international",
|
515
|
+
reinterpret_cast<VALUE (*)(...)>(rb_phone_number_dasherized_international), 0);
|
516
|
+
rb_define_method(rb_cPhoneNumber, "dasherized_national",
|
517
|
+
reinterpret_cast<VALUE (*)(...)>(rb_phone_number_dasherized_national), 0);
|
370
518
|
rb_define_method(rb_cPhoneNumber, "international", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_international),
|
371
519
|
0);
|
372
520
|
rb_define_method(rb_cPhoneNumber, "rfc3966", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_rfc3966), 0);
|
373
521
|
rb_define_method(rb_cPhoneNumber, "region_code", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_region_code), 0);
|
522
|
+
rb_define_method(rb_cPhoneNumber, "country", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_region_code), 0);
|
374
523
|
rb_define_method(rb_cPhoneNumber, "country_code", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_country_code), 0);
|
375
524
|
rb_define_method(rb_cPhoneNumber, "type", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_type), 0);
|
525
|
+
rb_define_method(rb_cPhoneNumber, "area_code", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_area_code), 0);
|
376
526
|
rb_define_method(rb_cPhoneNumber, "eql?", reinterpret_cast<VALUE (*)(...)>(rb_phone_number_eql_eh), 1);
|
377
527
|
}
|
data/lib/mini_phone/version.rb
CHANGED
data/mini_phone.gemspec
CHANGED
@@ -27,7 +27,10 @@ Gem::Specification.new do |spec|
|
|
27
27
|
# Specify which files should be added to the gem when it is released.
|
28
28
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
29
29
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
30
|
-
`git ls-files -z
|
30
|
+
`git ls-files -z`
|
31
|
+
.split("\x0")
|
32
|
+
.reject { |f| f.match(%r{^(bin|spec|bench)/}) }
|
33
|
+
.reject { |f| f.start_with?('.') }
|
31
34
|
end
|
32
35
|
spec.bindir = 'exe'
|
33
36
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_phone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Ker-Seymer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Plugs directly in the the Google's native C++ [libphonenumber](https://github.com/google/libphonenumber)
|
14
14
|
for extemely _fast_ and _robust_ phone number parsing, validation, and formatting.
|
@@ -20,13 +20,6 @@ extensions:
|
|
20
20
|
- ext/mini_phone/extconf.rb
|
21
21
|
extra_rdoc_files: []
|
22
22
|
files:
|
23
|
-
- ".clang-format"
|
24
|
-
- ".github/workflows/ci.yml"
|
25
|
-
- ".github/workflows/release.yml"
|
26
|
-
- ".gitignore"
|
27
|
-
- ".rspec"
|
28
|
-
- ".rubocop.yml"
|
29
|
-
- ".travis.yml"
|
30
23
|
- CHANGELOG.md
|
31
24
|
- CODE_OF_CONDUCT.md
|
32
25
|
- Gemfile
|
data/.clang-format
DELETED
data/.github/workflows/ci.yml
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: CI
|
3
|
-
|
4
|
-
on: push
|
5
|
-
|
6
|
-
jobs:
|
7
|
-
build:
|
8
|
-
strategy:
|
9
|
-
fail-fast: false
|
10
|
-
matrix:
|
11
|
-
ruby: ["2.5", "2.6", "2.7", "3.0"]
|
12
|
-
os: [ubuntu-latest, macos-latest]
|
13
|
-
experimental: [false]
|
14
|
-
# include:
|
15
|
-
# - ruby: "truffleruby"
|
16
|
-
# os: ubuntu-latest
|
17
|
-
# experimental: true
|
18
|
-
# - ruby: "truffleruby"
|
19
|
-
# os: macos-latest
|
20
|
-
# experimental: true
|
21
|
-
name: ${{ matrix.ruby }} on ${{ matrix.os }}
|
22
|
-
runs-on: ${{ matrix.os }}
|
23
|
-
continue-on-error: ${{ matrix.experimental }}
|
24
|
-
env:
|
25
|
-
CI_EXPERIMENTAL: ${{ matrix.experimental }}
|
26
|
-
steps:
|
27
|
-
- uses: actions/checkout@v2
|
28
|
-
|
29
|
-
- uses: ruby/setup-ruby@v1
|
30
|
-
with:
|
31
|
-
ruby-version: ${{ matrix.ruby }}
|
32
|
-
|
33
|
-
- name: Install dependencies (system)
|
34
|
-
if: ${{ matrix.os == 'ubuntu-latest' }}
|
35
|
-
run: sudo apt-get -yqq install libphonenumber-dev
|
36
|
-
|
37
|
-
- name: Install dependencies (system)
|
38
|
-
if: ${{ matrix.os == 'macos-latest' }}
|
39
|
-
run: brew install --build-from-source libphonenumber && brew link libphonenumber
|
40
|
-
|
41
|
-
- name: Install dependencies (ruby)
|
42
|
-
run: gem install bundler && bundle install --jobs 4 --retry 3
|
43
|
-
|
44
|
-
- name: Compile
|
45
|
-
run: bundle exec rake compile
|
46
|
-
|
47
|
-
- name: RSpec
|
48
|
-
run: bundle exec rspec --format RSpec::Github::Formatter --format documentation
|
49
|
-
|
50
|
-
- name: Rubocop
|
51
|
-
run: bundle exec rubocop --format github
|
@@ -1,47 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: Release
|
3
|
-
|
4
|
-
on:
|
5
|
-
push:
|
6
|
-
tags:
|
7
|
-
- "v*"
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
build:
|
11
|
-
strategy:
|
12
|
-
fail-fast: false
|
13
|
-
matrix:
|
14
|
-
ruby: ["2.7"]
|
15
|
-
runs-on: ubuntu-latest
|
16
|
-
steps:
|
17
|
-
- uses: actions/checkout@v2
|
18
|
-
|
19
|
-
- uses: ruby/setup-ruby@v1
|
20
|
-
with:
|
21
|
-
ruby-version: ${{ matrix.ruby }}
|
22
|
-
|
23
|
-
- name: Install dependencies (system)
|
24
|
-
run: sudo apt-get -yqq install libphonenumber-dev
|
25
|
-
|
26
|
-
- name: Install dependencies (ruby)
|
27
|
-
run: gem install bundler && bundle install --jobs 4 --retry 3
|
28
|
-
|
29
|
-
- name: Login
|
30
|
-
run: |
|
31
|
-
mkdir -p ~/.gem
|
32
|
-
|
33
|
-
cat << EOF > ~/.gem/credentials
|
34
|
-
---
|
35
|
-
:github: ${GITHUB_AUTH_TOKEN}
|
36
|
-
:rubygems_api_key: ${RUBYGEMS_AUTH_TOKEN}
|
37
|
-
EOF
|
38
|
-
|
39
|
-
chmod 0600 ~/.gem/credentials
|
40
|
-
env:
|
41
|
-
GITHUB_AUTH_TOKEN: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
42
|
-
RUBYGEMS_AUTH_TOKEN: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
43
|
-
OWNER: ${{ github.repository_owner }}
|
44
|
-
|
45
|
-
- name: 🛳 Ship it
|
46
|
-
run: |
|
47
|
-
bundle exec rake publish:non_native
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
-
# configuration file. It makes it possible to enable/disable
|
3
|
-
# certain cops (checks) and to alter their behavior if they accept
|
4
|
-
# any parameters. The file can be placed either in your home
|
5
|
-
# directory or in some project directory.
|
6
|
-
#
|
7
|
-
# RuboCop will start looking for the configuration file in the directory
|
8
|
-
# where the inspected file is and continue its way up to the root directory.
|
9
|
-
#
|
10
|
-
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
-
AllCops:
|
12
|
-
TargetRubyVersion: 2.5
|
13
|
-
NewCops: enable
|
14
|
-
SuggestExtensions: false
|
15
|
-
Exclude:
|
16
|
-
- pkg/**/*
|
17
|
-
- tmp/**/*
|
18
|
-
|
19
|
-
Metrics/BlockLength:
|
20
|
-
Exclude:
|
21
|
-
- spec/**/*
|
22
|
-
- Rakefile
|
23
|
-
- Gemfile
|