cal_core/
utils.rs

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}