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}