1use std::str;
16use std::io::{BufRead};
17
18use crate::xml::Reader;
19use crate::xml::events::{self, Event};
20use crate::xml::events::attributes::Attribute;
21
22use crate::error;
23
24#[derive(Clone, Default, Serialize, Deserialize, Debug)]
26pub struct Defaults {
27 format: Format,
28 descriptor: Descriptor,
29}
30
31#[derive(Clone, Default, Serialize, Deserialize, Debug)]
33pub struct Metadata {
34 pub general: Option<Descriptor>,
35 pub fixed_line: Option<Descriptor>,
36 pub mobile: Option<Descriptor>,
37 pub toll_free: Option<Descriptor>,
38 pub premium_rate: Option<Descriptor>,
39 pub shared_cost: Option<Descriptor>,
40 pub personal_number: Option<Descriptor>,
41 pub voip: Option<Descriptor>,
42 pub pager: Option<Descriptor>,
43 pub uan: Option<Descriptor>,
44 pub emergency: Option<Descriptor>,
45 pub voicemail: Option<Descriptor>,
46 pub short_code: Option<Descriptor>,
47 pub standard_rate: Option<Descriptor>,
48 pub carrier: Option<Descriptor>,
49 pub no_international: Option<Descriptor>,
50
51 pub id: Option<String>,
52 pub country_code: Option<u16>,
53
54 pub international_prefix: Option<String>,
55 pub preferred_international_prefix: Option<String>,
56 pub national_prefix: Option<String>,
57 pub preferred_extension_prefix: Option<String>,
58
59 pub national_prefix_for_parsing: Option<String>,
60 pub national_prefix_transform_rule: Option<String>,
61
62 pub formats: Vec<Format>,
63 pub international_formats: Vec<Format>,
64
65 pub main_country_for_code: bool,
66 pub leading_digits: Option<String>,
67 pub mobile_number_portable: bool,
68
69 pub defaults: Defaults,
70}
71
72#[derive(Clone, Default, Serialize, Deserialize, Debug)]
74pub struct Format {
75 pub pattern: Option<String>,
76 pub format: Option<String>,
77 pub leading_digits: Vec<String>,
78 pub national_prefix_formatting_rule: Option<String>,
79 pub national_prefix_optional_when_formatting: bool,
80 pub domestic_carrier: Option<String>,
81}
82
83#[derive(Clone, Default, Serialize, Deserialize, Debug)]
85pub struct Descriptor {
86 pub national_number: Option<String>,
87 pub possible_length: Vec<u16>,
88 pub possible_local_length: Vec<u16>,
89 pub example: Option<String>,
90}
91
92pub fn load<R: BufRead>(reader: R) -> Result<Vec<Metadata>, error::LoadMetadata> {
94 metadata(&mut Reader::from_reader(reader))
95}
96
97fn metadata<R: BufRead>(reader: &mut Reader<R>) -> Result<Vec<Metadata>, error::LoadMetadata> {
98 let mut buffer = Vec::new();
99 let mut result = Vec::new();
100
101 loop {
102 match reader.read_event(&mut buffer)? {
103 Event::Text(_) |
104 Event::Comment(_) |
105 Event::DocType(_) =>
106 (),
107
108 Event::Start(ref e) => {
109 match e.name() {
110 b"phoneNumberMetadata" =>
111 continue,
112
113 b"territories" =>
114 result.extend(territories(reader)?),
115
116 name =>
117 ignore(reader, name)?,
118 }
119 }
120
121 Event::End(ref e) if e.name() != b"phoneNumberMetadata" =>
122 return Err(error::Metadata::MismatchedTag(
123 str::from_utf8(e.name())?.into()).into()),
124
125 Event::End(ref e) if e.name() == b"phoneNumberMetadata" =>
126 return Ok(result),
127
128 event =>
129 return Err(error::Metadata::UnhandledEvent {
130 phase: "metadata".into(),
131 event: format!("{:?}", event),
132 }.into())
133 }
134 }
135}
136
137fn territories<R: BufRead>(reader: &mut Reader<R>) -> Result<Vec<Metadata>, error::LoadMetadata> {
138 let mut buffer = Vec::new();
139 let mut result = Vec::new();
140
141 loop {
142 match reader.read_event(&mut buffer)? {
143 Event::Text(_) |
144 Event::Comment(_) =>
145 (),
146
147 Event::Start(ref e) => {
148 match e.name() {
149 b"territory" =>
150 result.push(territory(reader, e)?),
151
152 name =>
153 ignore(reader, name)?,
154 }
155 }
156
157 Event::End(ref e) if e.name() == b"territories" =>
158 return Ok(result),
159
160 Event::End(ref e) =>
161 return Err(error::Metadata::MismatchedTag(
162 str::from_utf8(e.name())?.into()).into()),
163
164 Event::Eof =>
165 return Err(error::Metadata::UnexpectedEof.into()),
166
167 event =>
168 return Err(error::Metadata::UnhandledEvent {
169 phase: "territories".into(),
170 event: format!("{:?}", event),
171 }.into())
172 }
173 }
174}
175
176fn territory<'a, R: BufRead>(reader: &mut Reader<R>, e: &events::BytesStart<'a>) -> Result<Metadata, error::LoadMetadata> {
177 let mut buffer = Vec::new();
178 let mut meta = Metadata::default();
179
180 for attr in e.attributes() {
181 let Attribute { key, value } = attr?;
182
183 match (str::from_utf8(key)?, str::from_utf8(&value)?) {
184 ("id", value) =>
185 meta.id = Some(value.into()),
186
187 ("countryCode", value) =>
188 meta.country_code = Some(value.parse()?),
189
190 ("internationalPrefix", value) =>
191 meta.international_prefix = Some(value.into()),
192
193 ("preferredInternationalPrefix", value) =>
194 meta.preferred_international_prefix = Some(value.into()),
195
196 ("nationalPrefix", value) =>
197 meta.national_prefix = Some(value.into()),
198
199 ("preferredExtnPrefix", value) =>
200 meta.preferred_extension_prefix = Some(value.into()),
201
202 ("nationalPrefixForParsing", value) =>
203 meta.national_prefix_for_parsing = Some(value.into()),
204
205 ("nationalPrefixTransformRule", value) =>
206 meta.national_prefix_transform_rule = Some(value.into()),
207
208 ("mainCountryForCode", value) =>
209 meta.main_country_for_code = value.parse()?,
210
211 ("leadingDigits", value) =>
212 meta.leading_digits = Some(value.into()),
213
214 ("mobileNumberPortableRegion", value) =>
215 meta.mobile_number_portable = value.parse()?,
216
217 ("nationalPrefixFormattingRule", value) =>
218 meta.defaults.format.national_prefix_formatting_rule = Some(value.into()),
219
220 ("nationalPrefixOptionalWhenFormatting", value) =>
221 meta.defaults.format.national_prefix_optional_when_formatting = value.parse()?,
222
223 ("carrierCodeFormattingRule", value) =>
224 meta.defaults.format.domestic_carrier = Some(value.into()),
225
226 (name, value) =>
227 return Err(error::Metadata::UnhandledAttribute {
228 phase: "format".into(),
229 name: name.into(),
230 value: value.into()
231 }.into())
232 }
233 }
234
235 loop {
236 match reader.read_event(&mut buffer)? {
237 Event::Text(_) |
238 Event::Comment(_) =>
239 (),
240
241 Event::Start(ref e) => {
242 match e.name() {
243 name @ b"references" |
244 name @ b"areaCodeOptional" =>
245 ignore(reader, name)?,
246
247 name @ b"generalDesc" =>
248 meta.general = Some(descriptor(reader, &meta, name)?),
249
250 name @ b"fixedLine" =>
251 meta.fixed_line = Some(descriptor(reader, &meta, name)?),
252
253 name @ b"mobile" =>
254 meta.mobile = Some(descriptor(reader, &meta, name)?),
255
256 name @ b"tollFree" =>
257 meta.toll_free = Some(descriptor(reader, &meta, name)?),
258
259 name @ b"premiumRate" =>
260 meta.premium_rate = Some(descriptor(reader, &meta, name)?),
261
262 name @ b"sharedCost" =>
263 meta.shared_cost = Some(descriptor(reader, &meta, name)?),
264
265 name @ b"personalNumber" =>
266 meta.personal_number = Some(descriptor(reader, &meta, name)?),
267
268 name @ b"voip" =>
269 meta.voip = Some(descriptor(reader, &meta, name)?),
270
271 name @ b"pager" =>
272 meta.pager = Some(descriptor(reader, &meta, name)?),
273
274 name @ b"uan" =>
275 meta.uan = Some(descriptor(reader, &meta, name)?),
276
277 name @ b"emergency" =>
278 meta.emergency = Some(descriptor(reader, &meta, name)?),
279
280 name @ b"voicemail" =>
281 meta.voicemail = Some(descriptor(reader, &meta, name)?),
282
283 name @ b"noInternationalDialling" =>
284 meta.no_international = Some(descriptor(reader, &meta, name)?),
285
286 name @ b"availableFormats" => {
287 let (national, international) = formats(reader, &meta, name)?;
288
289 meta.formats = national;
290 meta.international_formats = international;
291 }
292
293 name =>
294 return Err(error::Metadata::UnhandledElement {
295 phase: "territory".into(),
296 name: str::from_utf8(name)?.into(),
297 }.into())
298 }
299 }
300
301 Event::End(ref e) if e.name() == b"territory" =>
302 return Ok(meta),
303
304 Event::End(ref e) =>
305 return Err(error::Metadata::MismatchedTag(
306 str::from_utf8(e.name())?.into()).into()),
307
308 Event::Eof =>
309 return Err(error::Metadata::UnexpectedEof.into()),
310
311 event =>
312 return Err(error::Metadata::UnhandledEvent {
313 phase: "territory".into(),
314 event: format!("{:?}", event),
315 }.into())
316 }
317 }
318}
319
320fn descriptor<R: BufRead>(reader: &mut Reader<R>, meta: &Metadata, name: &[u8]) -> Result<Descriptor, error::LoadMetadata> {
321 let mut buffer = Vec::new();
322 let mut descriptor = meta.defaults.descriptor.clone();
323
324 fn lengths(value: &str) -> Result<Vec<u16>, error::LoadMetadata> {
325 let mut result = Vec::new();
326
327 for part in value.split(',').map(str::trim) {
328 if part.as_bytes()[0] == b'[' {
329 let mut parts = part.split('-');
330
331 if let (Some(start), Some(end)) = (parts.next(), parts.next()) {
332 let start = start[1 ..].parse::<u16>()?;
333 let end = end[.. end.len() - 1].parse::<u16>()?;
334
335 for i in start .. end + 1 {
336 result.push(i);
337 }
338 }
339 }
340 else {
341 result.push(part.parse()?);
342 }
343 }
344
345 Ok(result)
346 }
347
348 loop {
349 match reader.read_event(&mut buffer)? {
350 Event::Text(_) |
351 Event::Comment(_) =>
352 (),
353
354 Event::Start(ref e) => {
355 match e.name() {
356 name @ b"nationalNumberPattern" =>
357 descriptor.national_number = Some(text(reader, name)?),
358
359 name @ b"exampleNumber" =>
360 descriptor.example = Some(text(reader, name)?),
361
362 name =>
363 return Err(error::Metadata::UnhandledElement {
364 phase: "descriptor".into(),
365 name: str::from_utf8(name)?.into(),
366 }.into())
367 }
368 }
369
370 Event::Empty(ref e) => {
371 match e.name() {
372 b"possibleLengths" => {
373 for attr in e.attributes() {
374 let Attribute {key, value } = attr?;
375
376 match (str::from_utf8(key)?, str::from_utf8(&value)?) {
377 ("national", value) =>
378 descriptor.possible_length = lengths(value)?,
379
380 ("localOnly", value) =>
381 descriptor.possible_local_length = lengths(value)?,
382
383 (name, value) =>
384 return Err(error::Metadata::UnhandledAttribute {
385 phase: "descriptor::possibleLength".into(),
386 name: name.into(),
387 value: value.into()
388 }.into())
389
390 }
391 }
392 }
393
394 name =>
395 return Err(error::Metadata::UnhandledElement {
396 phase: "descriptor".into(),
397 name: str::from_utf8(name)?.into(),
398 }.into())
399 }
400 }
401
402 Event::End(ref e) if e.name() == name =>
403 return Ok(descriptor),
404
405 Event::End(ref e) =>
406 return Err(error::Metadata::MismatchedTag(
407 str::from_utf8(e.name())?.into()).into()),
408
409 Event::Eof =>
410 return Err(error::Metadata::UnexpectedEof.into()),
411
412 event =>
413 return Err(error::Metadata::UnhandledEvent {
414 phase: "descriptor".into(),
415 event: format!("{:?}", event),
416 }.into())
417 }
418 }
419}
420
421fn formats<R: BufRead>(reader: &mut Reader<R>, meta: &Metadata, name: &[u8]) -> Result<(Vec<Format>, Vec<Format>), error::LoadMetadata> {
422 let mut buffer = Vec::new();
423 let mut national = Vec::new();
424 let mut international = Vec::new();
425
426 loop {
427 match reader.read_event(&mut buffer)? {
428 Event::Text(_) |
429 Event::Comment(_) =>
430 (),
431
432 Event::Start(ref e) => {
433 match e.name() {
434 name @ b"numberFormat" => {
435 let (natl, intl) = format(reader, meta, name, e)?;
436
437 national.push(natl);
438
439 if let Some(intl) = intl {
440 international.push(intl);
441 }
442 }
443
444 name =>
445 return Err(error::Metadata::UnhandledElement {
446 phase: "formats".into(),
447 name: str::from_utf8(name)?.into(),
448 }.into())
449 }
450 }
451
452 Event::End(ref e) if e.name() == name =>
453 return Ok((national, international)),
454
455 Event::End(ref e) =>
456 return Err(error::Metadata::MismatchedTag(
457 str::from_utf8(e.name())?.into()).into()),
458
459 Event::Eof =>
460 return Err(error::Metadata::UnexpectedEof.into()),
461
462 event =>
463 return Err(error::Metadata::UnhandledEvent {
464 phase: "formats".into(),
465 event: format!("{:?}", event),
466 }.into())
467 }
468 }
469}
470
471fn format<'a, R: BufRead>(reader: &mut Reader<R>, meta: &Metadata, name: &[u8], e: &events::BytesStart<'a>) -> Result<(Format, Option<Format>), error::LoadMetadata> {
472 let mut buffer = Vec::new();
473
474 let mut format = meta.defaults.format.clone();
475 let mut international = None;
476
477 println!("{:?}", format);
478
479 for attr in e.attributes() {
480 let Attribute { key, value } = attr?;
481
482 match (str::from_utf8(key)?, str::from_utf8(&value)?) {
483 ("pattern", value) =>
484 format.pattern = Some(value.into()),
485
486 ("nationalPrefixFormattingRule", value) =>
487 format.national_prefix_formatting_rule = Some(value.into()),
488
489 ("nationalPrefixOptionalWhenFormatting", value) =>
490 format.national_prefix_optional_when_formatting = value.parse()?,
491
492 ("carrierCodeFormattingRule", value) =>
493 format.domestic_carrier = Some(value.into()),
494
495 (name, value) =>
496 return Err(error::Metadata::UnhandledAttribute {
497 phase: "format".into(),
498 name: name.into(),
499 value: value.into()
500 }.into())
501 }
502 }
503
504 loop {
505 match reader.read_event(&mut buffer)? {
506 Event::Text(_) |
507 Event::Comment(_) =>
508 (),
509
510 Event::Start(ref e) => {
511 match e.name() {
512 name @ b"leadingDigits" =>
513 format.leading_digits.push(text(reader, name)?),
514
515 name @ b"format" => {
516 let text = text(reader, name)?;
517
518 format.format = Some(text.clone());
519 international = Some(text);
520 }
521
522 name @ b"intlFormat" => {
523 let text = text(reader, name)?;
524
525 if text == "NA" {
526 international = None;
527 }
528 else {
529 international = Some(text);
530 }
531 }
532
533 name =>
534 return Err(error::Metadata::UnhandledElement {
535 phase: "format".into(),
536 name: str::from_utf8(name)?.into(),
537 }.into())
538 }
539 }
540
541 Event::End(ref e) if e.name() == name => {
542 let international = international.map(|v| {
543 let mut format = format.clone();
544 format.format = Some(v);
545 format
546 });
547
548 return Ok((format, international));
549 }
550
551 Event::End(ref e) =>
552 return Err(error::Metadata::MismatchedTag(
553 str::from_utf8(e.name())?.into()).into()),
554
555 Event::Eof =>
556 return Err(error::Metadata::UnexpectedEof.into()),
557
558 event =>
559 return Err(error::Metadata::UnhandledEvent {
560 phase: "format".into(),
561 event: format!("{:?}", event),
562 }.into())
563 }
564 }
565}
566
567fn ignore<R: BufRead>(reader: &mut Reader<R>, name: &[u8]) -> Result<(), error::LoadMetadata> {
568 let mut buffer = Vec::new();
569
570 loop {
571 match reader.read_event(&mut buffer)? {
572 Event::Text(_) |
573 Event::Comment(_) |
574 Event::Empty(_) =>
575 (),
576
577 Event::Start(ref e) => {
578 match e.name() {
579 name =>
580 ignore(reader, name)?,
581 }
582 }
583
584 Event::End(ref e) if e.name() == name =>
585 return Ok(()),
586
587 Event::End(ref e) =>
588 return Err(error::Metadata::MismatchedTag(
589 str::from_utf8(e.name())?.into()).into()),
590
591 Event::Eof =>
592 return Err(error::Metadata::UnexpectedEof.into()),
593
594 event =>
595 return Err(error::Metadata::UnhandledEvent {
596 phase: "ignore".into(),
597 event: format!("{:?}", event),
598 }.into())
599 }
600 }
601}
602
603fn text<R: BufRead>(reader: &mut Reader<R>, name: &[u8]) -> Result<String, error::LoadMetadata> {
604 let mut buffer = Vec::new();
605 let mut result = String::new();
606
607 loop {
608 match reader.read_event(&mut buffer)? {
609 Event::Text(ref e) =>
610 result.push_str(str::from_utf8(e)?),
611
612 Event::End(ref e) if e.name() == name =>
613 return Ok(result),
614
615 Event::End(ref e) =>
616 return Err(error::Metadata::MismatchedTag(
617 str::from_utf8(e.name())?.into()).into()),
618
619 Event::Eof =>
620 return Err(error::Metadata::UnexpectedEof.into()),
621
622 event =>
623 return Err(error::Metadata::UnhandledEvent {
624 phase: "text".into(),
625 event: format!("{:?}", event),
626 }.into())
627 }
628 }
629}