@@ -15,19 +15,48 @@ use std::io::prelude::*;
15
15
use std:: path:: Path ;
16
16
17
17
use fluent_bundle:: { FluentBundle , FluentResource , FluentValue } ;
18
+ use fluent_locale:: negotiate_languages;
18
19
19
20
lazy_static ! {
20
21
static ref RESOURCES : HashMap <String , Vec <FluentResource >> = build_resources( ) ;
21
22
static ref BUNDLES : HashMap <String , FluentBundle <' static >> = build_bundles( ) ;
23
+ static ref LOCALES : Vec <String > = build_locale_list( ) ;
24
+ }
25
+
26
+ pub struct Fallback < ' res > {
27
+ default : Option < & ' res str > ,
28
+ availables : & ' res Vec < String > ,
29
+ }
30
+
31
+ impl < ' res > Fallback < ' res > {
32
+ pub fn new ( available_locales : & ' res Vec < String > ) -> Self {
33
+ Self {
34
+ default : Some ( "en-US" ) ,
35
+ availables : available_locales,
36
+ }
37
+ }
38
+
39
+ pub fn order < ' t , T : AsRef < str > > ( & ' t self , targets : & ' t [ T ] ) -> Vec < & ' t str > {
40
+ negotiate_languages (
41
+ targets,
42
+ & self . availables ,
43
+ self . default ,
44
+ & fluent_locale:: NegotiationStrategy :: Filtering ,
45
+ )
46
+ }
22
47
}
23
48
24
49
pub struct I18NHelper {
25
50
bundles : & ' static HashMap < String , FluentBundle < ' static > > ,
51
+ fallback : Fallback < ' static > ,
26
52
}
27
53
28
54
impl I18NHelper {
29
55
pub fn new ( ) -> Self {
30
- Self { bundles : & * BUNDLES }
56
+ Self {
57
+ bundles : & * BUNDLES ,
58
+ fallback : Fallback :: new ( & * LOCALES ) ,
59
+ }
31
60
}
32
61
33
62
pub fn lookup (
@@ -58,17 +87,12 @@ impl I18NHelper {
58
87
text_id : & str ,
59
88
args : Option < & HashMap < & str , FluentValue > > ,
60
89
) -> String {
61
- if let Some ( val) = self . lookup ( lang, text_id, args) {
62
- val
63
- } else if lang != "en-US" {
64
- if let Some ( val) = self . lookup ( "en-US" , text_id, args) {
65
- val
66
- } else {
67
- format ! ( "Unknown localization {}" , text_id)
90
+ for l in self . fallback . order ( & [ lang] ) {
91
+ if let Some ( val) = self . lookup ( l, text_id, args) {
92
+ return val;
68
93
}
69
- } else {
70
- format ! ( "Unknown localization {}" , text_id)
71
94
}
95
+ format ! ( "Unknown localization {}" , text_id)
72
96
}
73
97
}
74
98
@@ -284,6 +308,14 @@ pub fn create_bundle(lang: &str, resources: &'static Vec<FluentResource>) -> Flu
284
308
bundle
285
309
}
286
310
311
+ fn build_locale_list ( ) -> Vec < String > {
312
+ let mut locale_list = Vec :: new ( ) ;
313
+ for key in RESOURCES . keys ( ) {
314
+ locale_list. push ( key. clone ( ) ) ;
315
+ }
316
+ locale_list
317
+ }
318
+
287
319
fn build_resources ( ) -> HashMap < String , Vec < FluentResource > > {
288
320
let mut all_resources = HashMap :: new ( ) ;
289
321
let entries = read_dir ( "./templates/fluent-resource" ) . unwrap ( ) ;
0 commit comments