pico_phone 0.3.2 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab7e3aefeff6473c01d13aeb8498261220e6ac2cef2c517a7e14acfe2967505e
4
- data.tar.gz: 9d2f1767ca6582c3dec028fd2f5e742fe6265a28787410c198b6073893866942
3
+ metadata.gz: 8c2d268e1535faacd152f3253cfc75d422b754709184ea993a9a6b5b00551a4b
4
+ data.tar.gz: 12852a51f54aa294e5dd9c3bb388e5175b7af96352a0e656ec17fbf52b25dbde
5
5
  SHA512:
6
- metadata.gz: 7046914f29929ccaaa19508dd1bcf7a2bb7d6a41d691d43c060d24b402337f9a382c7e240c8fd94c2b9949a794024e0ca72745fc53f7f1f17849577be81b1d16
7
- data.tar.gz: ee80361ab9897651f638b7990f93b9768c509d458179ced20baea073374c317eb0ab8a363a41251b4703db695fc2ecbf92bca59abb6d7fd2f86c3093e7b0c470
6
+ metadata.gz: 395c2dcfc9823ae7180b822a2a88b37b2e4fbdd5ef5da84f96a795c585b9aaf2e2e97bd50aa0d2b27261b1f408bf88b5654f6b7c3e6c377fa65a0376c4d1646f
7
+ data.tar.gz: 7d4c21dc53148a87a564b2f8da1aebded151af3d12b809e00dec99147935853400066c4aee08ecca04eeeb5a10c757bab7a31c01f431461aaeab6bbba244a9cd
@@ -11,14 +11,30 @@ if NATIVE_BUILD
11
11
  $INCFLAGS << " -I#{VENDOR_INSTALL}/include"
12
12
 
13
13
  static_libs = []
14
+ # geocoding depends on symbols from phonenumber, so it must precede it in
15
+ # the static link order.
16
+ static_libs << "#{VENDOR_INSTALL}/lib/libgeocoding.a"
14
17
  static_libs << "#{VENDOR_INSTALL}/lib/libphonenumber.a"
15
18
  static_libs << "#{VENDOR_INSTALL}/lib/libprotobuf.a"
19
+ # protobuf's own transitive static deps (UTF-8 validation, upb). Whole-archive
20
+ # linking (below) force-includes every object in libprotobuf.a, including
21
+ # members that reference these, so they must be present even though nothing
22
+ # in our own code calls them directly. libutf8_range and libutf8_validity are
23
+ # two CMake target names for the exact same compiled object (utf8_range.c.o)
24
+ # in this protobuf version — link only one, or whole-archive pulls in both
25
+ # copies and the linker sees duplicate symbols.
26
+ %w[libutf8_range libupb].each do |lib|
27
+ path = "#{VENDOR_INSTALL}/lib/#{lib}.a"
28
+ static_libs << path if File.exist?(path)
29
+ end
16
30
  static_libs += Dir["#{VENDOR_INSTALL}/lib/libabsl_*.a"].sort
17
31
 
18
32
  if RUBY_PLATFORM.include?("darwin")
19
33
  boost_prefix = `brew --prefix boost 2>/dev/null`.strip
20
34
  icu_prefix = `brew --prefix icu4c@78 2>/dev/null`.strip
21
35
 
36
+ $INCFLAGS << " -I#{icu_prefix}/include"
37
+
22
38
  %w[libboost_date_time libboost_thread libboost_atomic].each do |lib|
23
39
  static_libs << "#{boost_prefix}/lib/#{lib}.a"
24
40
  end
@@ -31,18 +47,37 @@ if NATIVE_BUILD
31
47
  # Ubuntu's libicu-dev static archives are not compiled with -fPIC and cannot
32
48
  # be linked into a shared object. Link ICU dynamically instead — libicu74 is
33
49
  # part of the Ubuntu 24.04 base system and is present in the target environment.
50
+ # ICU headers (for the geocoder) come from the system libicu-dev package.
34
51
  $LOCAL_LIBS << " -licui18n -licuuc -licudata -lpthread -ldl"
35
52
  end
36
53
 
37
- $LOCAL_LIBS << " " + static_libs.join(" ")
54
+ # Adding the geocoder introduces a circular reference among several small
55
+ # Abseil static archives (e.g. synchronization <-> log_internal). A plain
56
+ # left-to-right static link only pulls in archive members that satisfy an
57
+ # already-outstanding undefined symbol, which for a -bundle target isn't
58
+ # even validated until dlopen time — so a missing member surfaces as a
59
+ # runtime "symbol not found in flat namespace" error, not a link failure.
60
+ # Force-load every member of our own vendored archives so nothing gets
61
+ # silently dropped.
62
+ if RUBY_PLATFORM.include?("darwin")
63
+ $LOCAL_LIBS << " -Wl,-all_load " + static_libs.join(" ")
64
+ else
65
+ $LOCAL_LIBS << " -Wl,--whole-archive " + static_libs.join(" ") + " -Wl,--no-whole-archive"
66
+ end
38
67
 
39
68
  unless find_header("phonenumbers/phonenumberutil.h")
40
69
  abort "Could not find phonenumberutil.h in #{VENDOR_INSTALL}/include — run build_deps.sh first"
41
70
  end
71
+
72
+ unless find_header("phonenumbers/geocoding/phonenumber_offline_geocoder.h")
73
+ abort "Could not find the geocoding header in #{VENDOR_INSTALL}/include — run build_deps.sh first"
74
+ end
42
75
  else
43
76
  # Dynamic linking against system/Homebrew libraries (default developer workflow).
44
77
  if RUBY_PLATFORM.include?("darwin")
45
- %w[libphonenumber protobuf abseil].each do |pkg|
78
+ # icu4c@78 is already a transitive dependency of Homebrew's libphonenumber
79
+ # formula (which itself ships geocoding), so no extra install step needed.
80
+ %w[libphonenumber protobuf abseil icu4c@78].each do |pkg|
46
81
  prefix = `brew --prefix #{pkg} 2>/dev/null`.strip
47
82
  next if prefix.empty?
48
83
  $INCFLAGS << " -I#{prefix}/include"
@@ -50,17 +85,26 @@ else
50
85
  end
51
86
  end
52
87
 
53
- $LOCAL_LIBS << " -lphonenumber"
88
+ $LOCAL_LIBS << " -lphonenumber -lgeocoding"
54
89
 
55
90
  unless find_header("phonenumbers/phonenumberutil.h")
56
91
  abort <<~MSG
57
92
 
58
93
  Could not find libphonenumber. Please install it before installing this gem:
59
94
  macOS: brew install libphonenumber
60
- Ubuntu: sudo apt-get install libphonenumber-dev
95
+ Ubuntu: sudo apt-get install libphonenumber-dev libicu-dev
61
96
  Fedora: sudo dnf install libphonenumber-devel
62
97
  MSG
63
98
  end
99
+
100
+ unless find_header("phonenumbers/geocoding/phonenumber_offline_geocoder.h")
101
+ abort <<~MSG
102
+
103
+ Found libphonenumber but not its geocoding headers/library. On Debian/Ubuntu
104
+ this also needs ICU development headers:
105
+ sudo apt-get install libphonenumber-dev libicu-dev
106
+ MSG
107
+ end
64
108
  end
65
109
 
66
110
  create_makefile("pico_phone/pico_phone")
@@ -7,6 +7,13 @@
7
7
  #include <phonenumbers/phonenumberutil.h>
8
8
  #include <phonenumbers/shortnumberinfo.h>
9
9
 
10
+ // Ruby's regex engine (onigmo.h, pulled in via rice.hpp above) #defines UChar
11
+ // as unsigned char; ICU (pulled in transitively by the geocoding header)
12
+ // typedefs UChar as char16_t. We don't use Ruby's macro, so drop it before
13
+ // any ICU header is reachable.
14
+ #undef UChar
15
+ #include <phonenumbers/geocoding/phonenumber_offline_geocoder.h>
16
+
10
17
  using namespace Rice;
11
18
  using namespace i18n::phonenumbers;
12
19
 
@@ -190,6 +197,32 @@ static const ShortNumberInfo& GetShortNumberInfo() {
190
197
  return instance;
191
198
  }
192
199
 
200
+ // PhoneNumberOfflineGeocoder lazily loads its area-code-to-description data
201
+ // one (country calling code, language) file at a time on first lookup, and
202
+ // caches each loaded file for the life of this instance -- unlike phonelib's
203
+ // extended data, nothing gets pulled into memory until it's actually queried.
204
+ static const PhoneNumberOfflineGeocoder& GetGeocoder() {
205
+ static PhoneNumberOfflineGeocoder instance;
206
+ return instance;
207
+ }
208
+
209
+ VALUE parsed_number_geo_name(int argc, VALUE *argv, VALUE self) {
210
+ VALUE language;
211
+ rb_scan_args(argc, argv, "01", &language);
212
+
213
+ std::string language_code = RB_NIL_P(language)
214
+ ? "en"
215
+ : std::string(StringValuePtr(language), RSTRING_LEN(language));
216
+
217
+ PhoneNumber *phone_number;
218
+ TypedData_Get_Struct(self, PhoneNumber, &phone_number_type, phone_number);
219
+
220
+ Locale locale(language_code.c_str());
221
+ std::string description = GetGeocoder().GetDescriptionForNumber(*phone_number, locale);
222
+
223
+ return rb_str_new(description.c_str(), description.size());
224
+ }
225
+
193
226
  Object pico_phone_is_emergency_number(Object self, String number, String region) {
194
227
  return GetShortNumberInfo().IsEmergencyNumber(number.c_str(), region.c_str()) ? Qtrue : Qfalse;
195
228
  }
@@ -831,4 +864,5 @@ void Init_pico_phone() {
831
864
 
832
865
  rb_define_alloc_func(rb_cPhoneNumber, rb_phone_number_alloc);
833
866
  rb_define_method(rb_cPhoneNumber, "initialize", reinterpret_cast<VALUE (*)(...)>(phone_number_initialize), -1);
867
+ rb_define_method(rb_cPhoneNumber, "geo_name", reinterpret_cast<VALUE (*)(...)>(parsed_number_geo_name), -1);
834
868
  }
@@ -155,6 +155,14 @@ module PicoPhone
155
155
  # @return [String]
156
156
  def local_number; end
157
157
 
158
+ # Text description of the geographic area the number is from (e.g. a city
159
+ # or region), falling back to the country name when no finer-grained
160
+ # description is available. Returns an empty string for non-geographical
161
+ # numbers (e.g. toll-free) or numbers that could not be parsed.
162
+ # @param language [String] two- or three-letter ISO 639 language code (default: "en")
163
+ # @return [String]
164
+ def geo_name(language = "en"); end
165
+
158
166
  # @param region [String] ISO 3166-1 alpha-2 region code
159
167
  # @return [Boolean]
160
168
  def valid_for_country?(region); end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PicoPhone
4
- VERSION = "0.3.2"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pico_phone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabi Jack
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-09 00:00:00.000000000 Z
11
+ date: 2026-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rice