1use std::collections::BTreeMap;
2use std::sync::OnceLock;
3
4use crate::i18n_bundle::{LocaleBundle, unpack_locales_from_cbor};
5
6include!(concat!(env!("OUT_DIR"), "/i18n_bundle.rs"));
8
9static I18N_BUNDLE: OnceLock<LocaleBundle> = OnceLock::new();
11
12fn bundle() -> &'static LocaleBundle {
13 I18N_BUNDLE.get_or_init(|| unpack_locales_from_cbor(I18N_BUNDLE_CBOR).unwrap_or_default())
14}
15
16fn locale_chain(locale: &str) -> Vec<String> {
19 let normalized = locale.replace('_', "-");
20 let mut chain = vec![normalized.clone()];
21 if let Some((base, _)) = normalized.split_once('-') {
22 chain.push(base.to_string());
23 }
24 chain.push("en".to_string());
25 chain
26}
27
28pub fn t(locale: &str, key: &str) -> String {
31 for candidate in locale_chain(locale) {
32 if let Some(map) = bundle().get(&candidate)
33 && let Some(value) = map.get(key)
34 {
35 return value.clone();
36 }
37 }
38 key.to_string()
39}
40
41pub fn all_keys() -> Vec<String> {
43 let Some(en) = bundle().get("en") else {
44 return Vec::new();
45 };
46 en.keys().cloned().collect()
47}
48
49pub fn en_messages() -> BTreeMap<String, String> {
51 bundle().get("en").cloned().unwrap_or_default()
52}