Merge pull request #445 from storytold/fix/398-tr-lookup

i18n: interface translations are looked up by hash (#398 follow-up)
This commit is contained in:
BFlat 2026-10-09 23:16:12 +07:00 committed by GitHub
commit 2a460986ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 16 additions and 8 deletions

View File

@ -14,7 +14,9 @@
//! drop a value, and `tr_args` itself cannot panic.
use std::cell::Cell;
use std::collections::HashMap;
use std::fmt::Display;
use std::sync::OnceLock;
thread_local! {
/// The resolved interface language ("en", "ja", "zh-hans", "zh-hant"); "en" until the first
@ -33,18 +35,24 @@ pub(crate) fn current() -> &'static str {
CURRENT.with(Cell::get)
}
/// The catalog for `language`: empty for English and for any language that has no rows yet.
fn catalog(language: &str) -> &'static [(&'static str, &'static str)] {
match language {
"zh-hans" => SIMPLIFIED_CHINESE,
"zh-hant" => TRADITIONAL_CHINESE,
_ => &[],
}
type Index = HashMap<&'static str, &'static str>;
/// The catalog for `language`, indexed by English source (built on first use: panels translate
/// hundreds of strings a frame); `None` for English and any language that has no rows yet.
fn catalog(language: &str) -> Option<&'static Index> {
static HANS: OnceLock<Index> = OnceLock::new();
static HANT: OnceLock<Index> = OnceLock::new();
let (index, rows) = match language {
"zh-hans" => (&HANS, SIMPLIFIED_CHINESE),
"zh-hant" => (&HANT, TRADITIONAL_CHINESE),
_ => return None,
};
Some(index.get_or_init(|| rows.iter().copied().collect()))
}
/// Translate one interface string: the current language's row for `text`, or `text` itself.
pub(crate) fn tr(text: &str) -> &str {
catalog(current()).iter().find(|(en, _)| *en == text).map_or(text, |(_, translated)| *translated)
catalog(current()).and_then(|c| c.get(text)).copied().unwrap_or(text)
}
/// Translate an interface string that carries values: each `{}` takes the next argument. A missing