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