1use phonenumber::country;
2use phonenumber::country::Id;
3use serde::{Deserialize, Serialize};
4
5pub fn clean_str_parse_country(country_code: &str, str: &str) -> String {
6 let id = country_code.parse().unwrap_or_else(|_| country::GB);
7 clean_str(id, str)
8}
9
10pub fn clean_str(country: Id, str: &str) -> String {
11 let clean: String = str
12 .replace("+", "")
13 .replace("<sip:", "")
14 .replace(">", "")
15 .split(":")
16 .next()
17 .unwrap_or(str)
18 .into();
19
20 parse_number(country, clean.clone())
21}
22
23pub fn format_number(str: &str, country_code: &str, format: NumberFormat) -> String {
24 let clean_str = clean_str_parse_country(country_code, str);
25 let plus_string = ["+", clean_str.as_str()].join("");
26 match format {
27 NumberFormat::National => national_number(clean_str, country_code),
28 NumberFormat::E164 => clean_str,
29 NumberFormat::E164Plus => plus_string,
30 }
31}
32
33fn national_number(str: String, country_code: &str) -> String {
34 let id = country_code.parse().unwrap_or_else(|_| country::GB);
35 parse_number(id, str)
36}
37
38fn parse_number(country: Id, clean: String) -> String {
39 match phonenumber::parse(Some(country), &clean) {
40 Ok(number) => {
41 let valid = phonenumber::is_valid(&number);
42 if valid {
43 format!("{}{}", number.code().value(), number.national().value())
44 } else {
45 clean
46 }
47 }
48 Err(_) => clean,
49 }
50}
51
52#[derive(Serialize, Deserialize, Clone)]
53pub enum NumberFormat {
54 #[serde(rename = "national")]
55 National,
56 #[serde(rename = "e164")]
57 E164,
58 #[serde(rename = "e164p")]
59 E164Plus,
60}