Skip to main content

component_dwbase/
i18n_bundle.rs

1use std::collections::BTreeMap;
2use std::fs;
3use std::path::Path;
4
5use greentic_types::cbor::canonical;
6
7pub type LocaleBundle = BTreeMap<String, BTreeMap<String, String>>;
8
9pub fn load_locale_files(dir: &Path) -> Result<LocaleBundle, String> {
10    let mut locales = LocaleBundle::new();
11    if !dir.exists() {
12        return Ok(locales);
13    }
14    for entry in fs::read_dir(dir).map_err(|err| err.to_string())? {
15        let entry = entry.map_err(|err| err.to_string())?;
16        let path = entry.path();
17        if path.extension().and_then(|ext| ext.to_str()) != Some("json") {
18            continue;
19        }
20        let Some(stem) = path.file_stem().and_then(|stem| stem.to_str()) else {
21            continue;
22        };
23        if stem == "locales" {
24            continue;
25        }
26        let raw = fs::read_to_string(&path).map_err(|err| err.to_string())?;
27        let map: BTreeMap<String, String> =
28            serde_json::from_str(&raw).map_err(|err| err.to_string())?;
29        locales.insert(stem.to_string(), map);
30    }
31    Ok(locales)
32}
33
34pub fn pack_locales_to_cbor(locales: &LocaleBundle) -> Result<Vec<u8>, String> {
35    canonical::to_canonical_cbor_allow_floats(locales).map_err(|err| err.to_string())
36}
37
38#[allow(dead_code)]
39pub fn unpack_locales_from_cbor(bytes: &[u8]) -> Result<LocaleBundle, String> {
40    canonical::from_cbor(bytes).map_err(|err| err.to_string())
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn pack_roundtrip_contains_en() {
49        let mut locales = LocaleBundle::new();
50        let mut en = BTreeMap::new();
51        en.insert("qa.install.title".to_string(), "Install".to_string());
52        locales.insert("en".to_string(), en);
53
54        let cbor = pack_locales_to_cbor(&locales).expect("pack locales");
55        let decoded = unpack_locales_from_cbor(&cbor).expect("decode locales");
56        assert!(decoded.contains_key("en"));
57    }
58}