use once_cell::sync::Lazy;
use regex::Regex;
use std::collections::HashSet;
pub(crate) static IPV4_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$").unwrap());
static TWO_LABEL_SUFFIXES: Lazy<HashSet<&'static str>> = Lazy::new(|| {
[
"co.uk", "org.uk", "gov.uk", "ac.uk", "net.uk", "me.uk", "ltd.uk", "plc.uk", "sch.uk",
"co.jp", "ac.jp", "or.jp", "ne.jp", "go.jp", "gr.jp", "ed.jp", "lg.jp",
"com.au", "net.au", "org.au", "edu.au", "gov.au", "asn.au", "id.au",
"co.nz", "net.nz", "org.nz", "govt.nz", "ac.nz", "school.nz",
"com.br", "net.br", "org.br", "gov.br", "edu.br",
"com.cn", "net.cn", "org.cn", "gov.cn", "edu.cn", "ac.cn",
"co.za", "net.za", "org.za", "gov.za", "ac.za",
"co.kr", "ne.kr", "or.kr", "re.kr", "go.kr", "ac.kr",
"co.in", "net.in", "org.in", "gov.in", "ac.in",
"co.il", "net.il", "org.il", "gov.il", "ac.il", "muni.il",
"com.mx", "net.mx", "org.mx", "gob.mx", "edu.mx",
"com.ar", "net.ar", "org.ar", "gov.ar",
"com.hk", "net.hk", "org.hk", "gov.hk", "edu.hk",
"com.tw", "net.tw", "org.tw", "gov.tw", "edu.tw",
"com.sg", "net.sg", "org.sg", "gov.sg", "edu.sg", "per.sg",
"com.tr", "net.tr", "org.tr", "gov.tr", "edu.tr", "k12.tr",
]
.iter()
.copied()
.collect()
});
pub fn registrable_domain(host: &str) -> String {
if host.is_empty() || IPV4_RE.is_match(host) {
return host.to_string();
}
let labels: Vec<&str> = host.split('.').collect();
if labels.len() <= 2 {
return host.to_string();
}
let tail2 = format!("{}.{}", labels[labels.len() - 2], labels[labels.len() - 1]);
if TWO_LABEL_SUFFIXES.contains(tail2.as_str()) {
return labels[labels.len() - 3..].join(".");
}
labels[labels.len() - 2..].join(".")
}