Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lookup fallback to t! #68

Merged
merged 2 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ rust-i18n = "2"

Load macro and init translations in `lib.rs` or `main.rs`:

```rust,no_run
```rust,compile_fail,no_run
// Load I18n macro, for allow you use `t!` macro in anywhere.
#[macro_use]
extern crate rust_i18n;
Expand Down
18 changes: 18 additions & 0 deletions crates/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ fn generate_code(

static _RUST_I18N_FALLBACK_LOCALE: Option<&'static str> = #fallback;

/// Lookup fallback locales
///
/// For example: `"zh-Hant-CN-x-private1-private2"` -> `"zh-Hant-CN-x-private1"` -> `"zh-Hant-CN"` -> `"zh-Hant"` -> `"zh"`.
///
/// https://datatracker.ietf.org/doc/html/rfc4647#section-3.4
#[inline]
#[allow(missing_docs)]
pub fn _rust_i18n_lookup_fallback(locale: &str) -> Option<&str> {
locale.rfind('-').map(|n| locale[..n].trim_end_matches("-x"))
}

/// Get I18n text by locale and key
#[inline]
#[allow(missing_docs)]
Expand All @@ -189,6 +200,13 @@ fn generate_code(
return value.to_string();
}

let mut current_locale = locale;
while let Some(fallback_locale) = _rust_i18n_lookup_fallback(current_locale) {
if let Some(value) = _RUST_I18N_BACKEND.translate(fallback_locale, key) {
return value.to_string();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里有可能避免 to_string 没?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

哦,这个仅是 fallback 的时候才会触发,还好。你试试看 to_string 能否避免,如果可以那就减少一次创建 String,不行的话也可以的。

Copy link
Contributor Author

@varphone varphone Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不行,translate() 返回的是 Option<&str>,而 _rust_i18n_translate() 返回的是 String

}
current_locale = fallback_locale;
}

if let Some(fallback) = _RUST_I18N_FALLBACK_LOCALE {
if let Some(value) = _RUST_I18N_BACKEND.translate(fallback, key) {
Expand Down
14 changes: 13 additions & 1 deletion tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ mod tests {
fn test_available_locales() {
assert_eq!(
rust_i18n::available_locales!(),
&["en", "ja", "pt", "zh-CN"]
&["en", "ja", "pt", "zh", "zh-CN"]
);
}

Expand Down Expand Up @@ -287,4 +287,16 @@ mod tests {
"こんにちは test3"
);
}

#[test]
fn test_lookup_fallback() {
assert_eq!(
t!("missing.lookup-fallback", locale = "zh-CN"),
"在 zh-XXX 中缺失的的翻译。"
);
assert_eq!(
t!("missing.default", locale = "zh-CN", fallback = "en"),
"This is missing key fallbacked to en."
);
}
}
2 changes: 2 additions & 0 deletions tests/locales/zh.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
missing:
lookup-fallback: 在 zh-XXX 中缺失的的翻译。