@@ -22,46 +22,35 @@ 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 ,
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 ,
46
35
& fluent_locale:: NegotiationStrategy :: Filtering ,
47
- )
48
- }
36
+ ) . into_iter ( ) . map ( |x| x . to_string ( ) ) . collect ( ) )
37
+ } ) . collect ( )
49
38
}
50
39
51
40
pub struct I18NHelper {
52
41
bundles : & ' static HashMap < String , FluentBundle < ' static > > ,
53
- fallback : Fallback < ' static > ,
42
+ fallbacks : & ' static HashMap < String , Vec < String > > ,
54
43
}
55
44
56
45
impl I18NHelper {
57
46
pub fn new ( ) -> Self {
58
47
Self {
59
48
bundles : & * BUNDLES ,
60
- fallback : Fallback :: new ( & * LOCALES ) ,
49
+ fallbacks : & * FALLBACKS ,
61
50
}
62
51
}
63
52
64
- pub fn lookup (
53
+ pub fn lookup_single_language (
65
54
& self ,
66
55
lang : & str ,
67
56
text_id : & str ,
@@ -83,19 +72,42 @@ impl I18NHelper {
83
72
panic ! ( "Unknown language {}" , lang)
84
73
}
85
74
}
86
- pub fn lookup_with_fallback (
75
+
76
+ // Traverse the fallback chain,
77
+ pub fn lookup (
87
78
& self ,
88
79
lang : & str ,
89
80
text_id : & str ,
90
81
args : Option < & HashMap < & str , FluentValue > > ,
91
82
) -> 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) {
94
90
return val;
95
91
}
96
92
}
97
93
format ! ( "Unknown localization {}" , text_id)
98
94
}
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
+ }
99
111
}
100
112
101
113
#[ derive( Default ) ]
@@ -197,7 +209,7 @@ impl HelperDef for I18NHelper {
197
209
. as_bool ( )
198
210
. expect ( "Pontoon must be boolean" ) ;
199
211
200
- let response = self . lookup_with_fallback ( lang, & id, args. as_ref ( ) ) ;
212
+ let response = self . lookup ( lang, & id, args. as_ref ( ) ) ;
201
213
if pontoon {
202
214
out. write ( & format ! ( "<span data-l10n-id='{}'>" , id) )
203
215
. map_err ( RenderError :: with) ?;
@@ -288,7 +300,7 @@ impl HelperDef for TeamHelper {
288
300
if lang == "en-US" {
289
301
let english = team[ "website_data" ] [ id] . as_str ( ) . unwrap ( ) ;
290
302
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 ) {
292
304
out. write ( & value) . map_err ( RenderError :: with) ?;
293
305
} else {
294
306
let english = team[ "website_data" ] [ id] . as_str ( ) . unwrap ( ) ;
@@ -334,14 +346,6 @@ pub fn create_bundle(lang: &str, resources: &'static Vec<FluentResource>) -> Flu
334
346
bundle
335
347
}
336
348
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
349
fn build_resources ( ) -> HashMap < String , Vec < FluentResource > > {
346
350
let mut all_resources = HashMap :: new ( ) ;
347
351
let entries = read_dir ( "./locales" ) . unwrap ( ) ;
0 commit comments