55 lines
1.6 KiB
Rust
55 lines
1.6 KiB
Rust
use crate::i18n::loader::LOCALES;
|
|
use fluent_templates::{Loader, fluent_bundle::FluentValue};
|
|
use std::{
|
|
borrow::Cow,
|
|
collections::HashMap,
|
|
str::FromStr,
|
|
sync::{OnceLock, RwLock},
|
|
};
|
|
use unic_langid::LanguageIdentifier;
|
|
|
|
static SYSTEM_LOCALE: OnceLock<LanguageIdentifier> = OnceLock::new();
|
|
static TRANSLATION_CACHE: OnceLock<RwLock<HashMap<String, String>>> = OnceLock::new();
|
|
const CACHE_INITIAL_SIZE: usize = 30;
|
|
const CACHE_SIZE_LIMIT: usize = 1000;
|
|
|
|
fn get_system_locale() -> &'static LanguageIdentifier {
|
|
SYSTEM_LOCALE.get_or_init(|| {
|
|
let sys_lang = sys_locale::get_locale().unwrap_or_else(|| String::from("pt-BR"));
|
|
LanguageIdentifier::from_str(&sys_lang).expect("Invalid language")
|
|
})
|
|
}
|
|
|
|
fn get_translation_cache() -> &'static RwLock<HashMap<String, String>> {
|
|
TRANSLATION_CACHE.get_or_init(|| RwLock::new(HashMap::with_capacity(CACHE_INITIAL_SIZE)))
|
|
}
|
|
|
|
pub fn t(key: &str) -> String {
|
|
let cache = get_translation_cache();
|
|
|
|
{
|
|
let cache_read = cache.read().unwrap();
|
|
if let Some(cached) = cache_read.get(key) {
|
|
return cached.clone();
|
|
}
|
|
}
|
|
|
|
let result = LOCALES.lookup(get_system_locale(), key);
|
|
|
|
let mut cache_write = cache.write().unwrap();
|
|
|
|
if cache_write.len() >= CACHE_SIZE_LIMIT {
|
|
cache_write.clear();
|
|
}
|
|
|
|
cache_write.insert(key.to_string(), result.clone());
|
|
result
|
|
}
|
|
|
|
pub fn t_with_args(key: &str, args: &HashMap<&'static str, String>) -> String {
|
|
let mut map = HashMap::new();
|
|
for (key, value) in args {
|
|
map.insert(Cow::Borrowed(*key), FluentValue::from(value));
|
|
}
|
|
LOCALES.lookup_with_args(get_system_locale(), key, &map)
|
|
}
|