use serde_json::Value;
pub(crate) const JSON: &str = include_str!("nsid_renames.json");
pub(crate) struct Pair {
pub(crate) old: String,
pub(crate) new: String,
closes_at: i64,
}
pub(crate) fn pairs() -> &'static [Pair] {
static PAIRS: std::sync::OnceLock<Vec<Pair>> = std::sync::OnceLock::new();
PAIRS.get_or_init(|| {
let doc: Value = serde_json::from_str(JSON).expect("the rename map is JSON");
let day = |d: &str| {
let date = chrono::NaiveDate::parse_from_str(d, "%Y-%m-%d").expect("the rename map's dates are YYYY-MM-DD");
(date + chrono::Days::new(1)).and_hms_opt(0, 0, 0).expect("midnight").and_utc().timestamp()
};
let delete_after = day(doc["deleteAfter"].as_str().expect("the rename map has a deleteAfter"));
let early = |old: &str| {
doc["closeEarlier"].as_object().into_iter().flatten().find_map(|(d, olds)| {
olds.as_array().is_some_and(|a| a.iter().any(|o| o == old)).then(|| day(d))
})
};
doc["renames"]
.as_object()
.expect("the rename map has a renames object")
.iter()
.map(|(old, new)| Pair {
old: old.clone(),
new: new.as_str().expect("the rename map's new names are strings").to_owned(),
closes_at: early(old).unwrap_or(delete_after),
})
.collect()
})
}
pub(crate) fn current_name_at(old: &str, now_unix: u64) -> Option<&'static str> {
let p = pairs().iter().find(|p| p.old == old)?;
(i64::try_from(now_unix).ok()? < p.closes_at).then_some(p.new.as_str())
}