mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-04-18 00:11:08 +08:00
* chore(deps): update rust crate rust-i18n to v4 * fix: migrate rust-i18n to v4 with Cow-first zero-copy approach - Adapt to v4 breaking changes: available_locales!() returns Vec<Cow<'static, str>> - Cache locales in LazyLock<Vec<Cow<'static, str>>> to avoid repeated Vec alloc + sort - Propagate Cow<'static, str> through resolve/current/system_language APIs - Fix t! macro args branch: into_owned() + Cow::Owned for type correctness - Eliminate double resolve in sync_locale (skip redundant set_locale indirection) - Replace .to_string() with .into_owned() / Cow passthrough in updater.rs --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
105 lines
3.2 KiB
Rust
105 lines
3.2 KiB
Rust
use rust_i18n::i18n;
|
|
use std::borrow::Cow;
|
|
use std::sync::LazyLock;
|
|
|
|
const DEFAULT_LANGUAGE: &str = "zh";
|
|
i18n!("locales", fallback = "zh");
|
|
|
|
static SUPPORTED_LOCALES: LazyLock<Vec<Cow<'static, str>>> = LazyLock::new(|| rust_i18n::available_locales!());
|
|
|
|
#[inline]
|
|
fn locale_alias(locale: &str) -> Option<&'static str> {
|
|
match locale {
|
|
"ja" | "ja-jp" | "jp" => Some("jp"),
|
|
"zh" | "zh-cn" | "zh-hans" | "zh-sg" | "zh-my" | "zh-chs" => Some("zh"),
|
|
"zh-tw" | "zh-hk" | "zh-hant" | "zh-mo" | "zh-cht" => Some("zhtw"),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
fn resolve_supported_language(language: &str) -> Option<Cow<'static, str>> {
|
|
if language.is_empty() {
|
|
return None;
|
|
}
|
|
let normalized = language.to_lowercase().replace('_', "-");
|
|
let segments: Vec<&str> = normalized.split('-').collect();
|
|
for i in (1..=segments.len()).rev() {
|
|
let prefix = segments[..i].join("-");
|
|
if let Some(alias) = locale_alias(&prefix)
|
|
&& let Some(found) = SUPPORTED_LOCALES.iter().find(|l| l.eq_ignore_ascii_case(alias))
|
|
{
|
|
return Some(found.clone());
|
|
}
|
|
if let Some(found) = SUPPORTED_LOCALES.iter().find(|l| l.eq_ignore_ascii_case(&prefix)) {
|
|
return Some(found.clone());
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
#[inline]
|
|
fn current_language(language: Option<&str>) -> Cow<'static, str> {
|
|
language
|
|
.filter(|lang| !lang.is_empty())
|
|
.and_then(resolve_supported_language)
|
|
.unwrap_or_else(system_language)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn system_language() -> Cow<'static, str> {
|
|
sys_locale::get_locale()
|
|
.as_deref()
|
|
.and_then(resolve_supported_language)
|
|
.unwrap_or(Cow::Borrowed(DEFAULT_LANGUAGE))
|
|
}
|
|
|
|
#[inline]
|
|
pub fn sync_locale(language: Option<&str>) {
|
|
rust_i18n::set_locale(¤t_language(language));
|
|
}
|
|
|
|
#[inline]
|
|
pub fn set_locale(language: &str) {
|
|
let lang = resolve_supported_language(language).unwrap_or(Cow::Borrowed(DEFAULT_LANGUAGE));
|
|
rust_i18n::set_locale(&lang);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn translate(key: &str) -> Cow<'_, str> {
|
|
rust_i18n::t!(key)
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! t {
|
|
($key:expr) => {
|
|
$crate::translate(&$key)
|
|
};
|
|
($key:expr, $($arg_name:ident = $arg_value:expr),*) => {
|
|
{
|
|
let mut _text = $crate::translate(&$key).into_owned();
|
|
$(
|
|
_text = _text.replace(&format!("{{{}}}", stringify!($arg_name)), &$arg_value);
|
|
)*
|
|
::std::borrow::Cow::<'static, str>::Owned(_text)
|
|
}
|
|
};
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::resolve_supported_language;
|
|
|
|
#[test]
|
|
fn test_resolve_supported_language() {
|
|
assert_eq!(resolve_supported_language("en").as_deref(), Some("en"));
|
|
assert_eq!(resolve_supported_language("en-US").as_deref(), Some("en"));
|
|
assert_eq!(resolve_supported_language("zh").as_deref(), Some("zh"));
|
|
assert_eq!(resolve_supported_language("zh-CN").as_deref(), Some("zh"));
|
|
assert_eq!(resolve_supported_language("zh-Hant").as_deref(), Some("zhtw"));
|
|
assert_eq!(resolve_supported_language("jp").as_deref(), Some("jp"));
|
|
assert_eq!(resolve_supported_language("ja-JP").as_deref(), Some("jp"));
|
|
assert_eq!(resolve_supported_language("fr"), None);
|
|
}
|
|
}
|