Skip to content

Commit bd690c2

Browse files
authored
Merge pull request #815 from renyuneyun/i18n-fallback
Add i18n fallback
2 parents 6f180d9 + f7258c1 commit bd690c2

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ lazy_static = "1.2.0"
99
fluent = "0.5"
1010
fluent-bundle = "0.6.0"
1111
fluent-syntax = "0.9.0"
12+
fluent-locale = "0.4.1"
1213
rand = "0.6"
1314
regex = "1"
1415
rocket = "0.4.1"

src/i18n.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,50 @@ use std::io::prelude::*;
1515
use std::path::Path;
1616

1717
use fluent_bundle::{FluentBundle, FluentResource, FluentValue};
18+
use fluent_locale::negotiate_languages;
1819

1920
lazy_static! {
2021
static ref CORE_RESOURCE: FluentResource =
2122
read_from_file("./locales/core.ftl").expect("cannot find core.ftl");
2223
static ref RESOURCES: HashMap<String, Vec<FluentResource>> = build_resources();
2324
static ref BUNDLES: HashMap<String, FluentBundle<'static>> = build_bundles();
25+
static ref LOCALES: Vec<String> = build_locale_list();
26+
}
27+
28+
pub struct Fallback<'res> {
29+
default: Option<&'res str>,
30+
availables: &'res Vec<String>,
31+
}
32+
33+
impl<'res> Fallback<'res> {
34+
pub fn new(available_locales: &'res Vec<String>) -> Self {
35+
Self {
36+
default: Some("en-US"),
37+
availables: available_locales,
38+
}
39+
}
40+
41+
pub fn order<'t, T: AsRef<str>>(&'t self, targets: &'t [T]) -> Vec<&'t str> {
42+
negotiate_languages(
43+
targets,
44+
&self.availables,
45+
self.default,
46+
&fluent_locale::NegotiationStrategy::Filtering,
47+
)
48+
}
2449
}
2550

2651
pub struct I18NHelper {
2752
bundles: &'static HashMap<String, FluentBundle<'static>>,
53+
fallback: Fallback<'static>,
2854
}
2955

3056
impl I18NHelper {
3157
pub fn new() -> Self {
32-
Self { bundles: &*BUNDLES }
58+
Self {
59+
bundles: &*BUNDLES,
60+
fallback: Fallback::new(&*LOCALES),
61+
}
3362
}
3463

3564
pub fn lookup(
@@ -60,17 +89,12 @@ impl I18NHelper {
6089
text_id: &str,
6190
args: Option<&HashMap<&str, FluentValue>>,
6291
) -> String {
63-
if let Some(val) = self.lookup(lang, text_id, args) {
64-
val
65-
} else if lang != "en-US" {
66-
if let Some(val) = self.lookup("en-US", text_id, args) {
67-
val
68-
} else {
69-
format!("Unknown localization {}", text_id)
92+
for l in self.fallback.order(&[lang]) {
93+
if let Some(val) = self.lookup(l, text_id, args) {
94+
return val;
7095
}
71-
} else {
72-
format!("Unknown localization {}", text_id)
7396
}
97+
format!("Unknown localization {}", text_id)
7498
}
7599
}
76100

@@ -310,6 +334,14 @@ pub fn create_bundle(lang: &str, resources: &'static Vec<FluentResource>) -> Flu
310334
bundle
311335
}
312336

337+
fn build_locale_list() -> Vec<String> {
338+
let mut locale_list = Vec::new();
339+
for key in RESOURCES.keys() {
340+
locale_list.push(key.clone());
341+
}
342+
locale_list
343+
}
344+
313345
fn build_resources() -> HashMap<String, Vec<FluentResource>> {
314346
let mut all_resources = HashMap::new();
315347
let entries = read_dir("./locales").unwrap();

0 commit comments

Comments
 (0)