use std::sync::atomic::{AtomicU8, Ordering};
pub trait Translate: Copy {
fn translate(self, lang_index: usize) -> &'static str;
}
static LANG_INDEX: AtomicU8 = AtomicU8::new(0);
#[inline]
pub fn current_lang_index() -> usize {
LANG_INDEX.load(Ordering::Relaxed) as usize
}
#[inline]
pub fn set_lang_index(idx: u8) {
LANG_INDEX.store(idx, Ordering::Relaxed);
}
#[inline]
pub fn t<K: Translate>(key: K) -> &'static str {
key.translate(current_lang_index())
}
#[macro_export]
macro_rules! table_lookup {
($row:expr, $idx:expr) => {{
let row: &[&str] = $row;
let idx = $idx;
let i = if idx < row.len() { idx } else { 0 };
let s = row[i];
if s.is_empty() { row[0] } else { s }
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Clone, Copy)]
enum TestKey {
Hello,
Bye,
}
static HELLO_ROW: [&str; 2] = ["Hello", "Привет"];
static BYE_ROW: [&str; 2] = ["Bye", ""];
impl Translate for TestKey {
fn translate(self, lang_index: usize) -> &'static str {
let row: &[&str] = match self {
TestKey::Hello => &HELLO_ROW,
TestKey::Bye => &BYE_ROW,
};
let s = row[lang_index.min(row.len() - 1)];
if s.is_empty() { row[0] } else { s }
}
}
#[test]
fn test_translate_index_0() {
set_lang_index(0);
assert_eq!(t(TestKey::Hello), "Hello");
assert_eq!(t(TestKey::Bye), "Bye");
}
#[test]
fn test_translate_index_1() {
set_lang_index(1);
assert_eq!(t(TestKey::Hello), "Привет");
}
#[test]
fn test_fallback_empty_cell() {
set_lang_index(1);
assert_eq!(t(TestKey::Bye), "Bye");
set_lang_index(0);
}
#[test]
fn test_set_and_get_index() {
set_lang_index(3);
assert_eq!(current_lang_index(), 3);
set_lang_index(0);
}
}