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}