phonenumber_fixed/metadata/metadata.rs
1// Copyright (C) 2017 1aim GmbH
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use regex_cache::CachedRegex;
16use crate::{
17 metadata::{Format, Descriptor},
18 phone_number::Type
19};
20
21/// Phone number metadata.
22#[derive(Clone, Debug)]
23pub struct Metadata {
24 pub(crate) descriptors: Descriptors,
25 pub(crate) id: String,
26 pub(crate) country_code: u16,
27
28 pub(crate) international_prefix: Option<CachedRegex>,
29 pub(crate) preferred_international_prefix: Option<String>,
30 pub(crate) national_prefix: Option<String>,
31 pub(crate) preferred_extension_prefix: Option<String>,
32 pub(crate) national_prefix_for_parsing: Option<CachedRegex>,
33 pub(crate) national_prefix_transform_rule: Option<String>,
34
35 pub(crate) formats: Vec<Format>,
36 pub(crate) international_formats: Vec<Format>,
37 pub(crate) main_country_for_code: bool,
38 pub(crate) leading_digits: Option<CachedRegex>,
39 pub(crate) mobile_number_portable: bool,
40}
41
42/// Descriptors for various types of phone number.
43#[derive(Clone, Debug)]
44pub struct Descriptors {
45 pub(crate) general: Descriptor,
46 pub(crate) fixed_line: Option<Descriptor>,
47 pub(crate) mobile: Option<Descriptor>,
48 pub(crate) toll_free: Option<Descriptor>,
49 pub(crate) premium_rate: Option<Descriptor>,
50 pub(crate) shared_cost: Option<Descriptor>,
51 pub(crate) personal_number: Option<Descriptor>,
52 pub(crate) voip: Option<Descriptor>,
53 pub(crate) pager: Option<Descriptor>,
54 pub(crate) uan: Option<Descriptor>,
55 pub(crate) emergency: Option<Descriptor>,
56 pub(crate) voicemail: Option<Descriptor>,
57 pub(crate) short_code: Option<Descriptor>,
58 pub(crate) standard_rate: Option<Descriptor>,
59 pub(crate) carrier: Option<Descriptor>,
60 pub(crate) no_international: Option<Descriptor>,
61}
62
63impl Metadata {
64 /// Descriptors for the various types of phone number.
65 pub fn descriptors(&self) -> &Descriptors {
66 &self.descriptors
67 }
68
69 /// The CLDR 2-letter representation of a country/region, with the exception
70 /// of "country calling codes" used for non-geographical entities, such as
71 /// Universal International Toll Free Number (+800). These are all given the
72 /// ID "001", since this is the numeric region code for the world according
73 /// to UN M.49: http://en.wikipedia.org/wiki/UN_M.49
74 pub fn id(&self) -> &str {
75 &self.id
76 }
77
78 /// The country calling code that one would dial from overseas when trying to
79 /// dial a phone number in this country. For example, this would be "64" for
80 /// New Zealand.
81 pub fn country_code(&self) -> u16 {
82 self.country_code
83 }
84
85 /// The international prefix of country A is the number that needs to be
86 /// dialled from country A to another country (country B). This is followed
87 /// by the country code for country B. Note that some countries may have more
88 /// than one international prefix, and for those cases, a regular expression
89 /// matching the international prefixes will be stored in this field.
90 pub fn international_prefix(&self) -> Option<&CachedRegex> {
91 self.international_prefix.as_ref()
92 }
93
94 /// If more than one international prefix is present, a preferred prefix can
95 /// be specified here for out-of-country formatting purposes. If this field
96 /// is not present, and multiple international prefixes are present, then "+"
97 /// will be used instead.
98 pub fn preferred_international_prefix(&self) -> Option<&str> {
99 self.preferred_extension_prefix.as_ref().map(AsRef::as_ref)
100 }
101
102 /// The national prefix of country A is the number that needs to be dialled
103 /// before the national significant number when dialling internally. This
104 /// would not be dialled when dialling internationally. For example, in New
105 /// Zealand, the number that would be locally dialled as 09 345 3456 would be
106 /// dialled from overseas as +64 9 345 3456. In this case, 0 is the national
107 /// prefix.
108 pub fn national_prefix(&self) -> Option<&str> {
109 self.national_prefix.as_ref().map(AsRef::as_ref)
110 }
111
112 /// The preferred prefix when specifying an extension in this country. This
113 /// is used for formatting only, and if this is not specified, a suitable
114 /// default should be used instead. For example, if you wanted extensions to
115 /// be formatted in the following way:
116 ///
117 /// 1 (365) 345 445 ext. 2345
118 /// " ext. " should be the preferred extension prefix.
119 pub fn preferred_extension_prefix(&self) -> Option<&str> {
120 self.preferred_extension_prefix.as_ref().map(AsRef::as_ref)
121 }
122
123 /// This field is used for cases where the national prefix of a country
124 /// contains a carrier selection code, and is written in the form of a
125 /// regular expression. For example, to dial the number 2222-2222 in
126 /// Fortaleza, Brazil (area code 85) using the long distance carrier Oi
127 /// (selection code 31), one would dial 0 31 85 2222 2222. Assuming the only
128 /// other possible carrier selection code is 32, the field will contain
129 /// "03[12]".
130 ///
131 /// When it is missing from the XML file, this field inherits the value of
132 /// national prefix, if that is present.
133 pub fn national_prefix_for_parsing(&self) -> Option<&CachedRegex> {
134 self.national_prefix_for_parsing.as_ref()
135 }
136
137 /// This field is only populated and used under very rare situations. For
138 /// example, mobile numbers in Argentina are written in two completely
139 /// different ways when dialed in-country and out-of-country (e.g. 0343 15
140 /// 555 1212 is exactly the same number as +54 9 343 555 1212).
141 ///
142 /// This field is used together with `national_prefix_for_parsing` to transform
143 /// the number into a particular representation for storing in the
144 /// phonenumber proto buffer in those rare cases.
145 pub fn national_prefix_transform_rule(&self) -> Option<&str> {
146 self.national_prefix_transform_rule.as_ref().map(AsRef::as_ref)
147 }
148
149 /// Note that the number format here is used for formatting only, not
150 /// parsing. Hence all the varied ways a user *may* write a number need not
151 /// be recorded - just the ideal way we would like to format it for them.
152 ///
153 /// When this element is absent, the national significant number will be
154 /// formatted as a whole without any formatting applied.
155 pub fn formats(&self) -> &[Format] {
156 &self.formats
157 }
158
159 /// This field is populated only when the national significant number is
160 /// formatted differently when it forms part of the INTERNATIONAL format and
161 /// NATIONAL format. A case in point is mobile numbers in Argentina: The
162 /// number, which would be written in INTERNATIONAL format as +54 9 343 555
163 /// 1212, will be written as 0343 15 555 1212 for NATIONAL format. In this
164 /// case, the prefix 9 is inserted when dialling from overseas, but otherwise
165 /// the prefix 0 and the carrier selection code
166 /// 15 (inserted after the area code of 343) is used.
167 ///
168 /// Note: this field is populated by setting a value for <intlFormat> inside
169 /// the <numberFormat> tag in the XML file. If <intlFormat> is not set then
170 /// it defaults to the same value as the <format> tag.
171 ///
172 /// Examples:
173 /// To set the <intlFormat> to a different value than the <format>:
174 /// <numberFormat pattern=....>
175 /// <format>$1 $2 $3</format>
176 /// <intlFormat>$1-$2-$3</intlFormat>
177 /// </numberFormat>
178 ///
179 /// To have a format only used for national formatting, set <intlFormat> to
180 /// "NA":
181 /// <numberFormat pattern=....>
182 /// <format>$1 $2 $3</format>
183 /// <intlFormat>NA</intlFormat>
184 /// </numberFormat>
185 pub fn international_formats(&self) -> &[Format] {
186 &self.international_formats
187 }
188
189 /// This field is set when this country is considered to be the main country
190 /// for a calling code. It may not be set by more than one country with the
191 /// same calling code, and it should not be set by countries with a unique
192 /// calling code. This can be used to indicate that "GB" is the main country
193 /// for the calling code "44" for example, rather than Jersey or the Isle of
194 /// Man.
195 pub fn is_main_country_for_code(&self) -> bool {
196 self.main_country_for_code
197 }
198
199 /// This field is populated only for countries or regions that share a
200 /// country calling code. If a number matches this pattern, it could belong
201 /// to this region. This is not intended as a replacement for
202 /// IsValidForRegion since a matching prefix is insufficient for a number to
203 /// be valid. Furthermore, it does not contain all the prefixes valid for a
204 /// region - for example, 800 numbers are valid for all NANPA countries and
205 /// are hence not listed here.
206 ///
207 /// This field should be a regular expression of the expected prefix match.
208 ///
209 /// It is used merely as a short-cut for working out which region a number
210 /// comes from in the case that there is only one, so leading digit prefixes
211 /// should not overlap.
212 pub fn leading_digits(&self) -> Option<&CachedRegex> {
213 self.leading_digits.as_ref()
214 }
215
216 /// This field is set when this country has implemented mobile number
217 /// portability. This means that transferring mobile numbers between carriers
218 /// is allowed. A consequence of this is that phone prefix to carrier mapping
219 /// is less reliable.
220 pub fn is_mobile_number_portable(&self) -> bool {
221 self.mobile_number_portable
222 }
223}
224
225impl Descriptors {
226 /// Get the proper descriptor for the given phone number type, if any.
227 pub fn get(&self, kind: Type) -> Option<&Descriptor> {
228 match kind {
229 Type::Unknown =>
230 Some(&self.general),
231
232 Type::FixedLine |
233 Type::FixedLineOrMobile =>
234 self.fixed_line.as_ref(),
235
236 Type::Mobile =>
237 self.mobile.as_ref(),
238
239 Type::TollFree =>
240 self.toll_free.as_ref(),
241
242 Type::PremiumRate =>
243 self.premium_rate.as_ref(),
244
245 Type::SharedCost =>
246 self.shared_cost.as_ref(),
247
248 Type::PersonalNumber =>
249 self.personal_number.as_ref(),
250
251 Type::Voip =>
252 self.voip.as_ref(),
253
254 Type::Pager =>
255 self.pager.as_ref(),
256
257 Type::Uan =>
258 self.uan.as_ref(),
259
260 Type::Emergency =>
261 self.emergency.as_ref(),
262
263 Type::Voicemail =>
264 self.voicemail.as_ref(),
265
266 Type::ShortCode =>
267 self.short_code.as_ref(),
268
269 Type::StandardRate =>
270 self.standard_rate.as_ref(),
271
272 Type::Carrier =>
273 self.carrier.as_ref(),
274
275 Type::NoInternational =>
276 self.no_international.as_ref(),
277 }
278 }
279
280 pub fn general(&self) -> &Descriptor {
281 &self.general
282 }
283
284 pub fn fixed_line(&self) -> Option<&Descriptor> {
285 self.fixed_line.as_ref()
286 }
287
288 pub fn mobile(&self) -> Option<&Descriptor> {
289 self.mobile.as_ref()
290 }
291
292 pub fn toll_free(&self) -> Option<&Descriptor> {
293 self.toll_free.as_ref()
294 }
295
296 pub fn premium_rate(&self) -> Option<&Descriptor> {
297 self.premium_rate.as_ref()
298 }
299
300 pub fn shared_cost(&self) -> Option<&Descriptor> {
301 self.shared_cost.as_ref()
302 }
303
304 pub fn personal_number(&self) -> Option<&Descriptor> {
305 self.personal_number.as_ref()
306 }
307
308 pub fn voip(&self) -> Option<&Descriptor> {
309 self.voip.as_ref()
310 }
311
312 pub fn pager(&self) -> Option<&Descriptor> {
313 self.pager.as_ref()
314 }
315
316 pub fn uan(&self) -> Option<&Descriptor> {
317 self.uan.as_ref()
318 }
319
320 pub fn emergency(&self) -> Option<&Descriptor> {
321 self.emergency.as_ref()
322 }
323
324 pub fn voicemail(&self) -> Option<&Descriptor> {
325 self.voicemail.as_ref()
326 }
327
328 pub fn short_code(&self) -> Option<&Descriptor> {
329 self.short_code.as_ref()
330 }
331
332 pub fn standard_rate(&self) -> Option<&Descriptor> {
333 self.standard_rate.as_ref()
334 }
335
336 pub fn carrier(&self) -> Option<&Descriptor> {
337 self.carrier.as_ref()
338 }
339
340 pub fn no_international(&self) -> Option<&Descriptor> {
341 self.no_international.as_ref()
342 }
343}