Skip to main content

component_qa/
i18n.rs

1use std::collections::BTreeMap;
2use std::sync::OnceLock;
3
4use crate::i18n_bundle::{LocaleBundle, unpack_locales_from_cbor};
5
6// Generated by build.rs: static embedded CBOR translation bundle.
7include!(concat!(env!("OUT_DIR"), "/i18n_bundle.rs"));
8
9// Decode once for process lifetime.
10static 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
16// Fallback precedence is deterministic:
17// exact locale -> base language -> en
18fn 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
28// Translation lookup function used throughout generated QA/setup code.
29// Extend by adding pluralization/context handling if your component needs it.
30pub 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
41// Returns canonical source key list (from `en`).
42pub 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
49// Returns English dictionary for diagnostics/tests/tools.
50pub fn en_messages() -> BTreeMap<String, String> {
51    bundle().get("en").cloned().unwrap_or_default()
52}