tetratto_l10n/
lib.rs

1use pathbufd::PathBufD;
2use serde::{Deserialize, Serialize};
3use std::{
4    collections::HashMap,
5    fs::{read_dir, read_to_string},
6    sync::{LazyLock, RwLock},
7};
8
9pub static ENGLISH_US: LazyLock<RwLock<LangFile>> = LazyLock::new(RwLock::default);
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct LangFile {
13    pub name: String,
14    pub version: String,
15    pub data: HashMap<String, String>,
16}
17
18impl Default for LangFile {
19    fn default() -> Self {
20        Self {
21            name: "com.tettrato.langs.testing:aa-BB".to_string(),
22            version: "0.0.0".to_string(),
23            data: HashMap::new(),
24        }
25    }
26}
27
28impl LangFile {
29    /// Check if a value exists in `data` (and isn't empty)
30    pub fn exists(&self, key: &str) -> bool {
31        if let Some(value) = self.data.get(key) {
32            if value.is_empty() {
33                return false;
34            }
35
36            return true;
37        }
38
39        false
40    }
41
42    /// Get a value from `data`, returns an empty string if it doesn't exist
43    pub fn get(&self, key: &str) -> String {
44        if !self.exists(key) {
45            if (self.name == "com.tettrato.langs.testing:aa-BB")
46                | (self.name == "com.tettrato.langs.testing:en-US")
47            {
48                return key.to_string();
49            } else {
50                // load english instead
51                let reader = ENGLISH_US
52                    .read()
53                    .expect("failed to pull reader for ENGLISH_US");
54                return reader.get(key);
55            }
56        }
57
58        self.data.get(key).unwrap().to_owned()
59    }
60}
61
62/// Read the `langs` directory and return a Hashmap containing all files
63pub fn read_langs() -> HashMap<String, LangFile> {
64    let mut out = HashMap::new();
65
66    let langs_dir = PathBufD::current().join("langs");
67    if let Ok(files) = read_dir(langs_dir) {
68        for file in files.into_iter() {
69            if file.is_err() {
70                continue;
71            }
72
73            let de: LangFile = match toml::from_str(&match read_to_string(file.unwrap().path()) {
74                Ok(f) => f,
75                Err(_) => continue,
76            }) {
77                Ok(de) => de,
78                Err(_) => continue,
79            };
80
81            if de.name.ends_with("en-US") {
82                let mut writer = ENGLISH_US
83                    .write()
84                    .expect("failed to pull writer for ENGLISH_US");
85                *writer = de.clone();
86                drop(writer);
87            }
88
89            out.insert(de.name.clone(), de);
90        }
91    }
92
93    // return
94    out
95}