Skip to content

Commit c857d5d

Browse files
committed
Special case English fallback, improve lifetimes
1 parent bd690c2 commit c857d5d

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

src/i18n.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,46 +22,35 @@ lazy_static! {
2222
read_from_file("./locales/core.ftl").expect("cannot find core.ftl");
2323
static ref RESOURCES: HashMap<String, Vec<FluentResource>> = build_resources();
2424
static ref BUNDLES: HashMap<String, FluentBundle<'static>> = build_bundles();
25-
static ref LOCALES: Vec<String> = build_locale_list();
25+
static ref LOCALES: Vec<&'static str> = RESOURCES.iter().map(|(l, _)| &**l).collect();
26+
static ref FALLBACKS: HashMap<String, Vec<String>> = build_fallbacks();
2627
}
2728

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,
29+
pub fn build_fallbacks() -> HashMap<String, Vec<String>> {
30+
LOCALES.iter().map(|locale| {
31+
(locale.to_string(), negotiate_languages(
32+
&[locale],
33+
&LOCALES,
34+
None,
4635
&fluent_locale::NegotiationStrategy::Filtering,
47-
)
48-
}
36+
).into_iter().map(|x| x.to_string()).collect())
37+
}).collect()
4938
}
5039

5140
pub struct I18NHelper {
5241
bundles: &'static HashMap<String, FluentBundle<'static>>,
53-
fallback: Fallback<'static>,
42+
fallbacks: &'static HashMap<String, Vec<String>>,
5443
}
5544

5645
impl I18NHelper {
5746
pub fn new() -> Self {
5847
Self {
5948
bundles: &*BUNDLES,
60-
fallback: Fallback::new(&*LOCALES),
49+
fallbacks: &*FALLBACKS,
6150
}
6251
}
6352

64-
pub fn lookup(
53+
pub fn lookup_single_language(
6554
&self,
6655
lang: &str,
6756
text_id: &str,
@@ -83,19 +72,42 @@ impl I18NHelper {
8372
panic!("Unknown language {}", lang)
8473
}
8574
}
86-
pub fn lookup_with_fallback(
75+
76+
// Traverse the fallback chain,
77+
pub fn lookup(
8778
&self,
8879
lang: &str,
8980
text_id: &str,
9081
args: Option<&HashMap<&str, FluentValue>>,
9182
) -> String {
92-
for l in self.fallback.order(&[lang]) {
93-
if let Some(val) = self.lookup(l, text_id, args) {
83+
for l in self.fallbacks.get(lang).expect("language not found") {
84+
if let Some(val) = self.lookup_single_language(l, text_id, args) {
85+
return val;
86+
}
87+
}
88+
if lang != "en-US" {
89+
if let Some(val) = self.lookup_single_language("en-US", text_id, args) {
9490
return val;
9591
}
9692
}
9793
format!("Unknown localization {}", text_id)
9894
}
95+
96+
// Don't fall back to English
97+
pub fn lookup_no_english(
98+
&self,
99+
lang: &str,
100+
text_id: &str,
101+
args: Option<&HashMap<&str, FluentValue>>,
102+
) -> Option<String> {
103+
for l in self.fallbacks.get(lang).expect("language not found") {
104+
if let Some(val) = self.lookup_single_language(l, text_id, args) {
105+
return Some(val);
106+
}
107+
}
108+
109+
None
110+
}
99111
}
100112

101113
#[derive(Default)]
@@ -197,7 +209,7 @@ impl HelperDef for I18NHelper {
197209
.as_bool()
198210
.expect("Pontoon must be boolean");
199211

200-
let response = self.lookup_with_fallback(lang, &id, args.as_ref());
212+
let response = self.lookup(lang, &id, args.as_ref());
201213
if pontoon {
202214
out.write(&format!("<span data-l10n-id='{}'>", id))
203215
.map_err(RenderError::with)?;
@@ -288,7 +300,7 @@ impl HelperDef for TeamHelper {
288300
if lang == "en-US" {
289301
let english = team["website_data"][id].as_str().unwrap();
290302
out.write(&english).map_err(RenderError::with)?;
291-
} else if let Some(value) = self.i18n.lookup(lang, &fluent_id, None) {
303+
} else if let Some(value) = self.i18n.lookup_no_english(lang, &fluent_id, None) {
292304
out.write(&value).map_err(RenderError::with)?;
293305
} else {
294306
let english = team["website_data"][id].as_str().unwrap();
@@ -334,14 +346,6 @@ pub fn create_bundle(lang: &str, resources: &'static Vec<FluentResource>) -> Flu
334346
bundle
335347
}
336348

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-
345349
fn build_resources() -> HashMap<String, Vec<FluentResource>> {
346350
let mut all_resources = HashMap::new();
347351
let entries = read_dir("./locales").unwrap();

0 commit comments

Comments
 (0)