#![allow(unused)]
use fnv::{FnvHashMap, FnvHashSet};
use itertools::Itertools;
use regex::{Regex, RegexBuilder};
pub const MIN_LENGTH_FOR_NSN: usize = 2;
pub const MAX_LENGTH_FOR_NSN: usize = 17;
pub const MAX_LENGTH_FOR_COUNTRY_CODE: usize = 3;
pub const UNKNOWN_REGION: &str = "ZZ";
pub const NANPA_COUNTRY_CODE: u32 = 1;
pub const COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX: &str = "3";
pub const PLUS_SIGN: char = '+';
pub const STAR_SIGN: char = '*';
pub const SHARP_SIGN: char = '#';
pub const RFC3966_EXTN_PREFIX: &str = ";ext=";
pub const RFC3966_PREFIX: &str = "tel:";
pub const RFC3966_PHONE_CONTEXT: &str = ";phone-context=";
pub const RFC3966_ISDN_SUBADDRESS: &str = ";isub=";
pub const REGION_CODE_FOR_NON_GEO_ENTITY: &str = "001";
lazy_static! {
pub static ref MOBILE_TOKEN_MAPPINGS: FnvHashMap<u16, &'static str> = {
let mut map = FnvHashMap::default();
map.insert(52, "1");
map.insert(54, "9");
map
};
pub static ref GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES: FnvHashSet<u16> = {
let mut set = FnvHashSet::default();
set.insert(86); set
};
pub static ref GEO_MOBILE_COUNTRIES: FnvHashSet<u16> = {
let mut set = FnvHashSet::default();
set.insert(52); set.insert(54); set.insert(55); set.insert(62); set.extend(GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES.iter());
set
};
pub static ref ASCII_MAPPINGS: FnvHashMap<char, char> = {
let mut map = FnvHashMap::default();
map.insert('0', '0');
map.insert('1', '1');
map.insert('2', '2');
map.insert('3', '3');
map.insert('4', '4');
map.insert('5', '5');
map.insert('6', '6');
map.insert('7', '7');
map.insert('8', '8');
map.insert('9', '9');
map
};
pub static ref DIALLABLE_CHAR_MAPPINGS: FnvHashMap<char, char> = {
let mut map = FnvHashMap::default();
map.extend(ASCII_MAPPINGS.iter());
map.insert(PLUS_SIGN, PLUS_SIGN);
map.insert(STAR_SIGN, STAR_SIGN);
map.insert(SHARP_SIGN, SHARP_SIGN);
map
};
pub static ref ALPHA_MAPPINGS: FnvHashMap<char, char> = {
let mut map = FnvHashMap::default();
map.insert('A', '2');
map.insert('B', '2');
map.insert('C', '2');
map.insert('D', '3');
map.insert('E', '3');
map.insert('F', '3');
map.insert('G', '4');
map.insert('H', '4');
map.insert('I', '4');
map.insert('J', '5');
map.insert('K', '5');
map.insert('L', '5');
map.insert('M', '6');
map.insert('N', '6');
map.insert('O', '6');
map.insert('P', '7');
map.insert('Q', '7');
map.insert('R', '7');
map.insert('S', '7');
map.insert('T', '8');
map.insert('U', '8');
map.insert('V', '8');
map.insert('W', '9');
map.insert('X', '9');
map.insert('Y', '9');
map.insert('Z', '9');
map.insert('a', '2');
map.insert('b', '2');
map.insert('c', '2');
map.insert('d', '3');
map.insert('e', '3');
map.insert('f', '3');
map.insert('g', '4');
map.insert('h', '4');
map.insert('i', '4');
map.insert('j', '5');
map.insert('k', '5');
map.insert('l', '5');
map.insert('m', '6');
map.insert('n', '6');
map.insert('o', '6');
map.insert('p', '7');
map.insert('q', '7');
map.insert('r', '7');
map.insert('s', '7');
map.insert('t', '8');
map.insert('u', '8');
map.insert('v', '8');
map.insert('w', '9');
map.insert('x', '9');
map.insert('y', '9');
map.insert('z', '9');
map
};
pub static ref ALPHA_PHONE_MAPPINGS: FnvHashMap<char, char> = {
let mut map = FnvHashMap::default();
map.extend(ASCII_MAPPINGS.iter());
map.extend(ALPHA_MAPPINGS.iter());
map
};
pub static ref ALL_PLUS_NUMBER_GROUPING_SYMBOLS: FnvHashMap<char, char> = {
let mut map = FnvHashMap::default();
for &c in ALPHA_MAPPINGS.keys() {
map.insert(c, c);
map.insert(c.to_lowercase().next().unwrap(), c);
}
map.extend(ASCII_MAPPINGS.iter());
map.insert('-', '-');
map.insert('\u{FF0D}', '-');
map.insert('\u{2010}', '-');
map.insert('\u{2011}', '-');
map.insert('\u{2012}', '-');
map.insert('\u{2013}', '-');
map.insert('\u{2014}', '-');
map.insert('\u{2015}', '-');
map.insert('\u{2212}', '-');
map.insert('/', '/');
map.insert('\u{FF0F}', '/');
map.insert(' ', ' ');
map.insert('\u{3000}', ' ');
map.insert('\u{2060}', ' ');
map.insert('.', '.');
map.insert('\u{FF0E}', '.');
map
};
pub static ref UNIQUE_INTERNATIONAL_PREFIX: Regex =
Regex::new(r"[\d]+(?:[~\x{2053}\x{223C}\x{FF5E}][\d]+)?").unwrap();
pub static ref VALID_PUNCTUATION: String =
String::from(r"-x\x{2010}-\x{2015}\x{2212}\x{30FC}\x{FF0D}-\x{FF0F} \x{00A0}\x{00AD}\x{200B}\x{2060}\x{3000}()\x{FF08}\x{FF09}\x{FF3B}\x{FF3D}.\[\]/~\x{2053}\x{223C}\x{FF5E}");
pub static ref DIGITS: String = String::from(r"\p{Nd}");
pub static ref PLUS_CHARS: String = String::from(r"\+\x{FF0B}");
pub static ref VALID_ALPHA: String = {
let mut string = String::new();
let clean = Regex::new(r"[, \[\]]").unwrap();
let alpha = ALPHA_MAPPINGS.keys().join("");
string.push_str(&clean.replace(&alpha, ""));
string.push_str(&clean.replace(&alpha.to_lowercase(), ""));
string
};
pub static ref PLUS_CHARS_PATTERN: Regex =
Regex::new(&format!("[{}]+", *PLUS_CHARS)).unwrap();
pub static ref SEPARATOR_PATTERN: Regex =
Regex::new(&format!("[{}]+", *VALID_PUNCTUATION)).unwrap();
pub static ref CAPTURING_DIGIT: Regex =
Regex::new(&format!("({})", *DIGITS)).unwrap();
pub static ref VALID_START_CHAR: Regex =
Regex::new(&format!("[{}{}]", *PLUS_CHARS, *DIGITS)).unwrap();
pub static ref SECOND_NUMBER_START: Regex =
Regex::new(r"[\\/] *x").unwrap();
pub static ref UNWANTED_END_CHARS: Regex =
Regex::new(r"[[\P{N}&&\P{L}]&&[^#]]+$").unwrap();
pub static ref VALID_ALPHA_PHONE: Regex =
Regex::new(r"(?:.*?[A-Za-z]){3}.*").unwrap();
pub static ref DEFAULT_EXTN_PREFIX: String = String::from(" ext. ");
pub static ref CAPTURING_EXTN_DIGITS: String = format!("({}{{0,7}})", *DIGITS);
pub static ref EXTN_PATTERNS_FOR_PARSING: String =
format!(r"{rfc3966_extn_prefix}{capturing_extn_digits}|[ \x{{00A0}}\t,]*(?:e?xt(?:ensi(?:o\x{{0301}}?|\x{{00F3}}))?n?|\x{{FF45}}?\x{{FF58}}\x{{FF54}}\x{{FF4E}}?|[{symbols}]|int|anexo|\x{{FF49}}\x{{FF4E}}\x{{FF54}})[:\.\x{{FF0E}}]?[ \x{{00A0}}\t,-]*{capturing_extn_digits}#?|[- ]+({digits}{{1,5}})#",
rfc3966_extn_prefix = RFC3966_EXTN_PREFIX,
capturing_extn_digits = *CAPTURING_EXTN_DIGITS,
symbols = r",;x\x{FF58}#\x{FF03}~\x{FF5E}",
digits = *DIGITS);
pub static ref EXTN_PATTERNS_FOR_MATCHING: String =
format!(r"{rfc3966_extn_prefix}{capturing_extn_digits}|[ \x{{00A0}}\t,]*(?:e?xt(?:ensi(?:o\x{{0301}}?|\x{{00F3}}))?n?|\x{{FF45}}?\x{{FF58}}\x{{FF54}}\x{{FF4E}}?|[{symbols}]|int|anexo|\x{{FF49}}\x{{FF4E}}\x{{FF54}})[:\.\x{{FF0E}}]?[ \x{{00A0}}\t,-]*{capturing_extn_digits}#?|[- ]+({digits}{{1,5}})#",
rfc3966_extn_prefix = RFC3966_EXTN_PREFIX,
capturing_extn_digits = *CAPTURING_EXTN_DIGITS,
symbols = r"x\x{FF58}#\x{FF03}~\x{FF5E}",
digits = *DIGITS);
pub static ref EXTN_PATTERN: Regex =
RegexBuilder::new(&format!(r"(?:{})$", *EXTN_PATTERNS_FOR_PARSING))
.case_insensitive(true)
.build()
.unwrap();
pub static ref VALID_PHONE_NUMBER: Regex =
RegexBuilder::new(&format!(r"(?:{})?", *EXTN_PATTERNS_FOR_PARSING))
.case_insensitive(true)
.build()
.unwrap();
pub static ref NON_DIGITS: Regex =
Regex::new(r"(\D+)").unwrap();
pub static ref FIRST_GROUP: Regex = Regex::new(r"(\$\d)").unwrap();
pub static ref NP: &'static str = "$NP";
pub static ref FG: &'static str = "$FG";
pub static ref CC: &'static str = "$CC";
pub static ref FIRST_GROUP_ONLY_PREFIX: Regex =
Regex::new(r"\(?\$1\)?").unwrap();
}