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