langbeam/
lib.rs

1use std::{
2    collections::HashMap,
3    sync::{LazyLock, RwLock},
4};
5use serde::{Serialize, Deserialize};
6use rainbeam_shared::fs;
7use pathbufd::PathBufD;
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: "net.rainbeam.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 == "net.rainbeam.langs.testing:aa-BB")
46                | (self.name == "net.rainbeam.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) = fs::read_dir(langs_dir) {
68        for file in files.into_iter() {
69            if file.is_err() {
70                continue;
71            }
72
73            let de: LangFile =
74                match serde_json::from_str(&match fs::read_to_string(file.unwrap().path()) {
75                    Ok(f) => f,
76                    Err(_) => continue,
77                }) {
78                    Ok(de) => de,
79                    Err(_) => continue,
80                };
81
82            if de.name.ends_with("en-US") {
83                let mut writer = ENGLISH_US
84                    .write()
85                    .expect("failed to pull writer for ENGLISH_US");
86                *writer = de.clone();
87                drop(writer);
88            }
89
90            out.insert(de.name.clone(), de);
91        }
92    }
93
94    // return
95    out
96}