Skip to content

Commit

Permalink
Add lookup fallback (RFC 4647) to t! (#68)
Browse files Browse the repository at this point in the history
* Add lookup fallback support to t!
* README.md: Fix doctest compile error
  • Loading branch information
varphone authored Jan 15, 2024
1 parent 403e6f7 commit cb93545
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
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();
}
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 中缺失的的翻译。

0 comments on commit cb93545

Please sign in to comment.