1
1
use quote:: quote;
2
2
use rust_i18n_support:: { is_debug, load_locales} ;
3
3
use std:: collections:: HashMap ;
4
- use syn:: { parse_macro_input, Expr , Ident , LitStr , Token } ;
4
+ use syn:: { parse_macro_input, Expr , Ident , LitBool , LitStr , Token } ;
5
5
6
6
struct Args {
7
7
locales_path : String ,
8
8
fallback : Option < String > ,
9
9
extend : Option < Expr > ,
10
+ auto_territory : bool ,
10
11
}
11
12
12
13
impl Args {
@@ -30,6 +31,9 @@ impl Args {
30
31
let val = input. parse :: < Expr > ( ) ?;
31
32
self . extend = Some ( val) ;
32
33
}
34
+ "auto_territory" => {
35
+ self . auto_territory = input. parse :: < LitBool > ( ) ?. value ( ) ;
36
+ }
33
37
_ => { }
34
38
}
35
39
@@ -56,6 +60,9 @@ impl syn::parse::Parse for Args {
56
60
/// # fn v3() {
57
61
/// i18n!("locales", fallback = "en");
58
62
/// # }
63
+ /// # fn v4() {
64
+ /// i18n!("locales", fallback = "en", auto_territory = true);
65
+ /// # }
59
66
/// ```
60
67
///
61
68
/// Ref: https://docs.rs/syn/latest/syn/parse/index.html
@@ -66,6 +73,7 @@ impl syn::parse::Parse for Args {
66
73
locales_path : String :: from ( "locales" ) ,
67
74
fallback : None ,
68
75
extend : None ,
76
+ auto_territory : false ,
69
77
} ;
70
78
71
79
if lookahead. peek ( LitStr ) {
@@ -88,6 +96,10 @@ impl syn::parse::Parse for Args {
88
96
///
89
97
/// Attribute `fallback` for set the fallback locale, if present `t` macro will use it as the fallback locale.
90
98
///
99
+ /// Attribute `auto_territory` for set the auto territory flag,
100
+ /// if true `t` macro will auto fallback to the language territory of the locale when missing,
101
+ /// like: `zh-SG` => `zh`, if `zh` still missing, then fallback to the `fallback` locale.
102
+ ///
91
103
/// ```no_run
92
104
/// # use rust_i18n::i18n;
93
105
/// # fn v1() {
@@ -99,6 +111,9 @@ impl syn::parse::Parse for Args {
99
111
/// # fn v3() {
100
112
/// i18n!("locales", fallback = "en");
101
113
/// # }
114
+ /// # fn v4() {
115
+ /// i18n!("locales", fallback = "en", auto_territory = true);
116
+ /// # }
102
117
/// ```
103
118
#[ proc_macro]
104
119
pub fn i18n ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
@@ -155,6 +170,12 @@ fn generate_code(
155
170
}
156
171
} ;
157
172
173
+ let auto_territory = if args. auto_territory {
174
+ quote ! { true }
175
+ } else {
176
+ quote ! { false }
177
+ } ;
178
+
158
179
let extend_code = if let Some ( extend) = args. extend {
159
180
quote ! {
160
181
let backend = backend. extend( #extend) ;
@@ -180,6 +201,7 @@ fn generate_code(
180
201
} ) ;
181
202
182
203
static _RUST_I18N_FALLBACK_LOCALE: Option <& ' static str > = #fallback;
204
+ static _RUST_I18N_AUTO_TERRITORY: bool = #auto_territory;
183
205
184
206
/// Get I18n text by locale and key
185
207
#[ inline]
@@ -189,6 +211,13 @@ fn generate_code(
189
211
return value. to_string( ) ;
190
212
}
191
213
214
+ if _RUST_I18N_AUTO_TERRITORY {
215
+ if let Some ( fallback) = rust_i18n:: language_territory( locale) {
216
+ if let Some ( value) = _RUST_I18N_BACKEND. translate( fallback, key) {
217
+ return value. to_string( ) ;
218
+ }
219
+ }
220
+ }
192
221
193
222
if let Some ( fallback) = _RUST_I18N_FALLBACK_LOCALE {
194
223
if let Some ( value) = _RUST_I18N_BACKEND. translate( fallback, key) {
0 commit comments