@@ -15,21 +15,50 @@ 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 CORE_RESOURCE : FluentResource =
21
22
read_from_file( "./locales/core.ftl" ) . expect( "cannot find core.ftl" ) ;
22
23
static ref RESOURCES : HashMap <String , Vec <FluentResource >> = build_resources( ) ;
23
24
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
+ }
24
49
}
25
50
26
51
pub struct I18NHelper {
27
52
bundles : & ' static HashMap < String , FluentBundle < ' static > > ,
53
+ fallback : Fallback < ' static > ,
28
54
}
29
55
30
56
impl I18NHelper {
31
57
pub fn new ( ) -> Self {
32
- Self { bundles : & * BUNDLES }
58
+ Self {
59
+ bundles : & * BUNDLES ,
60
+ fallback : Fallback :: new ( & * LOCALES ) ,
61
+ }
33
62
}
34
63
35
64
pub fn lookup (
@@ -60,17 +89,12 @@ impl I18NHelper {
60
89
text_id : & str ,
61
90
args : Option < & HashMap < & str , FluentValue > > ,
62
91
) -> 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;
70
95
}
71
- } else {
72
- format ! ( "Unknown localization {}" , text_id)
73
96
}
97
+ format ! ( "Unknown localization {}" , text_id)
74
98
}
75
99
}
76
100
@@ -310,6 +334,14 @@ pub fn create_bundle(lang: &str, resources: &'static Vec<FluentResource>) -> Flu
310
334
bundle
311
335
}
312
336
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
+
313
345
fn build_resources ( ) -> HashMap < String , Vec < FluentResource > > {
314
346
let mut all_resources = HashMap :: new ( ) ;
315
347
let entries = read_dir ( "./locales" ) . unwrap ( ) ;
0 commit comments