use rustc_hash::FxHashMap;
pub static CATALOG: std::sync::LazyLock<Catalog> = std::sync::LazyLock::new(Catalog::load);
const RAW: &str = include_str!(concat!(env!("OUT_DIR"), "/messages.toml"));
pub struct Catalog {
messages: FxHashMap<String, String>,
}
impl Catalog {
fn load() -> Self {
let table: toml::Table = RAW.parse().expect("bundled messages.toml is valid TOML");
let mut messages = FxHashMap::default();
flatten_table(&table, String::new(), &mut messages);
Self { messages }
}
pub fn get(&self, key: &str, vars: &[(&str, &str)]) -> String {
let template = match self.messages.get(key) {
Some(t) => t.as_str(),
None => return key.to_string(),
};
let mut out = template.to_string();
for (k, v) in vars {
out = out.replace(&format!("{{{k}}}"), v);
}
out
}
}
fn flatten_table(table: &toml::Table, prefix: String, out: &mut FxHashMap<String, String>) {
for (k, v) in table {
let key = if prefix.is_empty() {
k.clone()
} else {
format!("{prefix}.{k}")
};
match v {
toml::Value::String(s) => {
out.insert(key, s.clone());
}
toml::Value::Table(t) => {
flatten_table(t, key, out);
}
_ => {}
}
}
}
#[macro_export]
macro_rules! msg {
($key:expr) => {
$crate::messages::CATALOG.get($key, &[])
};
($key:expr, $($name:expr => $val:expr),+) => {
$crate::messages::CATALOG.get($key, &[$( ($name, &$val.to_string()) ),+])
};
}