mod config;
mod dict;
mod err;
mod key;
mod opts;
use std::sync::Once;
#[macro_export]
macro_rules! t {
($key:expr) => {
$crate::translate($key)
};
($key:expr, $($arg:tt)+) => {
{
let mut message = $crate::translate($key);
$(
message = message.replace("{}", $arg);
)+
message
}
};
}
use config::Config;
use std::sync::Mutex;
#[macro_use]
extern crate lazy_static;
struct CurrentDictionary {
default_locale: String,
dict: dict::Dictionary,
}
impl Default for CurrentDictionary {
fn default() -> Self {
let default_locale = "en".to_string();
let dict = Config::default().finish().unwrap();
CurrentDictionary {
default_locale,
dict,
}
}
}
impl CurrentDictionary {
fn set_locale(&mut self, locale: &str) {
self.default_locale = locale.to_string();
self.dict.default_locale = locale.to_string();
}
}
lazy_static! {
static ref _CURRENT_DICTIONARY: Mutex<CurrentDictionary> =
Mutex::new(CurrentDictionary::default());
}
static INITIALIZED: Once = Once::new();
pub fn init<T: rust_embed::RustEmbed>(default_locale: &str) {
let mut current_dict = _CURRENT_DICTIONARY.lock().unwrap();
INITIALIZED.call_once(|| {
current_dict.dict = Config::default().with_embed::<T>().finish().unwrap();
});
current_dict.set_locale(default_locale);
}
pub fn set_locale(locale: &str) {
_CURRENT_DICTIONARY.lock().unwrap().set_locale(locale);
}
pub fn locale() -> String {
_CURRENT_DICTIONARY.lock().unwrap().default_locale.clone()
}
#[allow(dead_code)]
pub fn translate(key: &str) -> String {
return _CURRENT_DICTIONARY
.lock()
.unwrap()
.dict
.t(key, None)
.unwrap_or_else(|_| key.to_string());
}
#[cfg(test)]
mod tests {
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "examples/locales/"]
struct Asset;
#[test]
fn test_translate() {
crate::init::<Asset>("en");
assert_eq!(t!("messages.zero"), "You have no messages.");
assert_eq!(t!("messages.hello", "world"), "Hello, world!");
crate::set_locale("de");
assert_eq!(t!("messages.hello", "world"), "messages.hello");
}
}