component-qa 0.5.0

WASM component hosting QA flows.
Documentation
use std::collections::BTreeMap;
use std::sync::OnceLock;

use crate::i18n_bundle::{LocaleBundle, unpack_locales_from_cbor};

// Generated by build.rs: static embedded CBOR translation bundle.
include!(concat!(env!("OUT_DIR"), "/i18n_bundle.rs"));

// Decode once for process lifetime.
static I18N_BUNDLE: OnceLock<LocaleBundle> = OnceLock::new();

fn bundle() -> &'static LocaleBundle {
    I18N_BUNDLE.get_or_init(|| unpack_locales_from_cbor(I18N_BUNDLE_CBOR).unwrap_or_default())
}

// Fallback precedence is deterministic:
// exact locale -> base language -> en
fn locale_chain(locale: &str) -> Vec<String> {
    let normalized = locale.replace('_', "-");
    let mut chain = vec![normalized.clone()];
    if let Some((base, _)) = normalized.split_once('-') {
        chain.push(base.to_string());
    }
    chain.push("en".to_string());
    chain
}

// Translation lookup function used throughout generated QA/setup code.
// Extend by adding pluralization/context handling if your component needs it.
pub fn t(locale: &str, key: &str) -> String {
    for candidate in locale_chain(locale) {
        if let Some(map) = bundle().get(&candidate)
            && let Some(value) = map.get(key)
        {
            return value.clone();
        }
    }
    key.to_string()
}

// Returns canonical source key list (from `en`).
pub fn all_keys() -> Vec<String> {
    let Some(en) = bundle().get("en") else {
        return Vec::new();
    };
    en.keys().cloned().collect()
}

// Returns English dictionary for diagnostics/tests/tools.
pub fn en_messages() -> BTreeMap<String, String> {
    bundle().get("en").cloned().unwrap_or_default()
}