@@ -22,46 +22,44 @@ lazy_static! {
22
22
read_from_file( "./locales/core.ftl" ) . expect( "cannot find core.ftl" ) ;
23
23
static ref RESOURCES : HashMap <String , Vec <FluentResource >> = build_resources( ) ;
24
24
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( ) ;
26
27
}
27
28
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
- }
29
+ pub fn build_fallbacks ( ) -> HashMap < String , Vec < String > > {
30
+ LOCALES
31
+ . iter ( )
32
+ . map ( |locale| {
33
+ (
34
+ locale. to_string ( ) ,
35
+ negotiate_languages (
36
+ & [ locale] ,
37
+ & LOCALES ,
38
+ None ,
39
+ & fluent_locale:: NegotiationStrategy :: Filtering ,
40
+ )
41
+ . into_iter ( )
42
+ . map ( |x| x. to_string ( ) )
43
+ . collect ( ) ,
44
+ )
45
+ } )
46
+ . collect ( )
49
47
}
50
48
51
49
pub struct I18NHelper {
52
50
bundles : & ' static HashMap < String , FluentBundle < ' static > > ,
53
- fallback : Fallback < ' static > ,
51
+ fallbacks : & ' static HashMap < String , Vec < String > > ,
54
52
}
55
53
56
54
impl I18NHelper {
57
55
pub fn new ( ) -> Self {
58
56
Self {
59
57
bundles : & * BUNDLES ,
60
- fallback : Fallback :: new ( & * LOCALES ) ,
58
+ fallbacks : & * FALLBACKS ,
61
59
}
62
60
}
63
61
64
- pub fn lookup (
62
+ pub fn lookup_single_language (
65
63
& self ,
66
64
lang : & str ,
67
65
text_id : & str ,
@@ -83,19 +81,42 @@ impl I18NHelper {
83
81
panic ! ( "Unknown language {}" , lang)
84
82
}
85
83
}
86
- pub fn lookup_with_fallback (
84
+
85
+ // Traverse the fallback chain,
86
+ pub fn lookup (
87
87
& self ,
88
88
lang : & str ,
89
89
text_id : & str ,
90
90
args : Option < & HashMap < & str , FluentValue > > ,
91
91
) -> String {
92
- for l in self . fallback . order ( & [ lang] ) {
93
- if let Some ( val) = self . lookup ( l, text_id, args) {
92
+ for l in self . fallbacks . get ( lang) . expect ( "language not found" ) {
93
+ if let Some ( val) = self . lookup_single_language ( l, text_id, args) {
94
+ return val;
95
+ }
96
+ }
97
+ if lang != "en-US" {
98
+ if let Some ( val) = self . lookup_single_language ( "en-US" , text_id, args) {
94
99
return val;
95
100
}
96
101
}
97
102
format ! ( "Unknown localization {}" , text_id)
98
103
}
104
+
105
+ // Don't fall back to English
106
+ pub fn lookup_no_english (
107
+ & self ,
108
+ lang : & str ,
109
+ text_id : & str ,
110
+ args : Option < & HashMap < & str , FluentValue > > ,
111
+ ) -> Option < String > {
112
+ for l in self . fallbacks . get ( lang) . expect ( "language not found" ) {
113
+ if let Some ( val) = self . lookup_single_language ( l, text_id, args) {
114
+ return Some ( val) ;
115
+ }
116
+ }
117
+
118
+ None
119
+ }
99
120
}
100
121
101
122
#[ derive( Default ) ]
@@ -197,7 +218,7 @@ impl HelperDef for I18NHelper {
197
218
. as_bool ( )
198
219
. expect ( "Pontoon must be boolean" ) ;
199
220
200
- let response = self . lookup_with_fallback ( lang, & id, args. as_ref ( ) ) ;
221
+ let response = self . lookup ( lang, & id, args. as_ref ( ) ) ;
201
222
if pontoon {
202
223
out. write ( & format ! ( "<span data-l10n-id='{}'>" , id) )
203
224
. map_err ( RenderError :: with) ?;
@@ -288,7 +309,7 @@ impl HelperDef for TeamHelper {
288
309
if lang == "en-US" {
289
310
let english = team[ "website_data" ] [ id] . as_str ( ) . unwrap ( ) ;
290
311
out. write ( & english) . map_err ( RenderError :: with) ?;
291
- } else if let Some ( value) = self . i18n . lookup ( lang, & fluent_id, None ) {
312
+ } else if let Some ( value) = self . i18n . lookup_no_english ( lang, & fluent_id, None ) {
292
313
out. write ( & value) . map_err ( RenderError :: with) ?;
293
314
} else {
294
315
let english = team[ "website_data" ] [ id] . as_str ( ) . unwrap ( ) ;
@@ -334,14 +355,6 @@ pub fn create_bundle(lang: &str, resources: &'static Vec<FluentResource>) -> Flu
334
355
bundle
335
356
}
336
357
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
-
345
358
fn build_resources ( ) -> HashMap < String , Vec < FluentResource > > {
346
359
let mut all_resources = HashMap :: new ( ) ;
347
360
let entries = read_dir ( "./locales" ) . unwrap ( ) ;
0 commit comments