1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3
4extern crate proc_macro;
9
10pub(crate) mod cookie;
11mod exprpath;
12mod files_tracker;
13#[cfg(not(feature = "ssr"))]
14pub(crate) mod fluent_entries;
15mod fluent_resources;
16mod languages;
17mod loader;
18#[cfg(not(feature = "ssr"))]
19pub(crate) mod tr_macros;
20#[cfg(not(feature = "ssr"))]
21mod translations_checker;
22#[cfg(not(feature = "ssr"))]
23mod translations_filler;
24
25pub(crate) use exprpath::evaluate_exprpath;
26use files_tracker::build_files_tracker_quote;
27#[cfg(not(feature = "ssr"))]
28pub(crate) use fluent_resources::FluentResources;
29pub(crate) use fluent_resources::{
30 build_fluent_resources_and_file_paths, FluentFilePaths,
31};
32use languages::build_languages_quote;
33pub(crate) use languages::ParsedLanguage;
34use loader::{I18nLoader, LitBoolExprOrIdent, LitBoolOrStr, TokenStreamStr};
35use quote::{quote, ToTokens};
36
37#[cfg(feature = "debug")]
38#[inline(always)]
39pub(crate) fn debug(msg: &str) {
40 #[allow(clippy::print_stdout)]
41 {
42 println!("[leptos-fluent/debug] {msg}");
43 };
44}
45
46#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", skip_all))]
104#[proc_macro]
105pub fn leptos_fluent(
106 input: proc_macro::TokenStream,
107) -> proc_macro::TokenStream {
108 let I18nLoader {
109 warnings,
110 fluent_file_paths,
111 children,
112 translations,
113 languages,
114 languages_path,
115 raw_languages_path,
116 locales_path,
117 core_locales_path,
118 default_language,
119 check_translations,
120 fill_translations,
121 customise,
122 provide_meta_context,
123 sync_html_tag_lang,
124 sync_html_tag_dir,
125 initial_language_from_url_param,
126 url_param,
127 initial_language_from_url_param_to_local_storage,
128 initial_language_from_url_param_to_session_storage,
129 initial_language_from_url_param_to_cookie,
130 initial_language_from_url_param_to_server_function,
131 set_language_to_url_param,
132 local_storage_key,
133 initial_language_from_local_storage,
134 initial_language_from_local_storage_to_cookie,
135 initial_language_from_local_storage_to_session_storage,
136 initial_language_from_local_storage_to_server_function,
137 set_language_to_local_storage,
138 session_storage_key,
139 initial_language_from_session_storage,
140 initial_language_from_session_storage_to_cookie,
141 initial_language_from_session_storage_to_local_storage,
142 initial_language_from_session_storage_to_server_function,
143 set_language_to_session_storage,
144 initial_language_from_navigator,
145 initial_language_from_navigator_to_local_storage,
146 initial_language_from_navigator_to_session_storage,
147 initial_language_from_navigator_to_cookie,
148 initial_language_from_navigator_to_server_function,
149 initial_language_from_accept_language_header,
150 set_language_from_navigator,
151 cookie_name,
152 cookie_attrs,
153 initial_language_from_cookie,
154 initial_language_from_cookie_to_local_storage,
155 initial_language_from_cookie_to_session_storage,
156 initial_language_from_cookie_to_server_function,
157 set_language_to_cookie,
158 initial_language_from_server_function,
159 initial_language_from_server_function_to_cookie,
160 initial_language_from_server_function_to_local_storage,
161 set_language_to_server_function,
162 url_path,
163 initial_language_from_url_path,
164 initial_language_from_url_path_to_cookie,
165 initial_language_from_url_path_to_local_storage,
166 initial_language_from_url_path_to_session_storage,
167 initial_language_from_url_path_to_server_function,
168 #[cfg(feature = "system")]
169 initial_language_from_system,
170 #[cfg(feature = "system")]
171 initial_language_from_system_to_data_file,
172 #[cfg(feature = "system")]
173 set_language_to_data_file,
174 #[cfg(feature = "system")]
175 initial_language_from_data_file,
176 #[cfg(feature = "system")]
177 data_file_key,
178 } = syn::parse_macro_input!(input as I18nLoader);
179
180 let n_languages = languages.len();
181 let languages_quote = build_languages_quote(&languages);
182
183 let files_tracker_quote = build_files_tracker_quote(
185 &fluent_file_paths,
186 &languages_path,
187 &core_locales_path,
188 );
189
190 #[cfg(feature = "nightly")]
192 let get_language_quote = quote! {
193 (::leptos::prelude::expect_context::<::leptos_fluent::I18n>())()
194 };
195
196 #[cfg(all(feature = "nightly", not(feature = "ssr")))]
197 let set_language_quote = quote! {
198 (::leptos::prelude::expect_context::<::leptos_fluent::I18n>())(l)
199 };
200
201 #[cfg(not(feature = "nightly"))]
202 let get_language_quote = quote! {
203 ::leptos::prelude::expect_context::<::leptos_fluent::I18n>().language.get()
204 };
205
206 #[cfg(all(not(feature = "nightly"), not(feature = "ssr")))]
207 let set_language_quote = quote! {
208 ::leptos::prelude::expect_context::<::leptos_fluent::I18n>().language.set(l)
209 };
210
211 let cookie_name_quote = match cookie_name.lit {
212 Some(ref lit) => quote! { #lit },
213 None => match cookie_name.expr {
214 Some(ref expr) => quote! { #expr },
215 None => quote! { "lf-lang" },
216 },
217 };
218
219 let cookie_attrs_quote = match cookie_attrs.lit {
220 Some(ref lit) => quote! { #lit },
221 None => match cookie_attrs.expr {
222 Some(ref expr) => quote! { #expr },
223 None => quote! { "" },
224 },
225 };
226
227 #[cfg(not(feature = "ssr"))]
228 let local_storage_key_quote = match local_storage_key.lit {
229 Some(ref lit) => quote! { #lit },
230 None => match local_storage_key.expr {
231 Some(ref expr) => quote! { #expr },
232 None => quote! { "lang" },
233 },
234 };
235
236 #[cfg(not(feature = "ssr"))]
237 let session_storage_key_quote = match session_storage_key.lit {
238 Some(ref lit) => quote! { #lit },
239 None => match session_storage_key.expr {
240 Some(ref expr) => quote! { #expr },
241 None => quote! { "lang" },
242 },
243 };
244
245 #[cfg(feature = "system")]
246 let data_file_key_quote = match data_file_key.lit {
247 Some(ref lit) => quote! { #lit },
248 None => match data_file_key.expr {
249 Some(ref expr) => quote! { #expr },
250 None => quote! { "leptos-fluent" },
251 },
252 };
253
254 #[cfg(all(feature = "system", not(feature = "ssr")))]
256 let initial_language_from_system_quote: proc_macro2::TokenStream = {
257 let initial_language_from_system_to_data_file_quote: proc_macro2::TokenStream = {
258 let effect_quote = quote! {
259 ::leptos_fluent::data_file::set(
260 #data_file_key_quote,
261 &l.id.to_string(),
262 );
263 };
264
265 initial_language_from_system_to_data_file.iter().map(|param| {
266 match param.expr {
267 Some(ref expr) => {
268 let q = quote! {
269 if lang.is_none() && #expr && !#data_file_key_quote.is_empty() {
270 #effect_quote
271 }
272 };
273 match param.exprpath {
274 Some(ref path) => quote!(#path{#q}),
275 None => q,
276 }
277 },
278 None => quote!(),
279 }
280 }).collect()
281 };
282
283 let effect_quote = quote! {
284 if let Ok(l) = ::leptos_fluent::__reexports::current_locale::current_locale() {
285 lang = ::leptos_fluent::l(&l, &LANGUAGES);
286 if let Some(l) = lang {
287 #initial_language_from_system_to_data_file_quote
288 }
289 }
290 };
291
292 initial_language_from_system
293 .iter()
294 .map(|param| match param.expr {
295 Some(ref expr) => {
296 let q = quote! {
297 if #expr && lang.is_none() {
298 #effect_quote
299 }
300 };
301 match param.exprpath {
302 Some(ref path) => quote!(#path{#q}),
303 None => q,
304 }
305 }
306 None => quote!(),
307 })
308 .collect()
309 };
310
311 #[cfg(all(not(feature = "system"), not(feature = "ssr")))]
312 let initial_language_from_system_quote = quote! {};
313
314 #[cfg(all(feature = "system", feature = "ssr"))]
315 {
316 _ = data_file_key;
317 _ = initial_language_from_system;
318 _ = initial_language_from_system_to_data_file;
319 }
320
321 #[cfg(feature = "system")]
322 let sync_language_with_data_file_quote: proc_macro2::TokenStream =
323 set_language_to_data_file
324 .iter()
325 .map(|param| {
326 let set_language_to_data_file_quote = match param.expr {
327 Some(ref expr) => quote! {
328 if #expr {
329 #data_file_key_quote
330 } else {
331 ""
332 }
333 },
334 None => quote! { "" },
335 };
336
337 let effect_quote = quote! {
339 ::leptos::prelude::Effect::new(move |_| {
340 if #set_language_to_data_file_quote.is_empty() {
341 return;
342 }
343 ::leptos_fluent::data_file::set(
344 #set_language_to_data_file_quote,
345 &#get_language_quote.id.to_string(),
346 );
347 });
348 };
349
350 match param.expr {
351 Some(ref expr) => {
352 let q = quote!(if #expr {#effect_quote});
353 match param.exprpath {
354 Some(ref path) => quote!(#path{#q}),
355 None => q,
356 }
357 }
358 None => quote!(),
359 }
360 })
361 .collect();
362
363 #[cfg(not(feature = "system"))]
364 let sync_language_with_data_file_quote = quote! {};
365
366 #[cfg(all(feature = "system", not(feature = "ssr")))]
367 let initial_language_from_data_file_quote: proc_macro2::TokenStream =
368 initial_language_from_data_file
369 .iter()
370 .map(|param| {
371 let initial_language_from_data_file_quote = match param.expr {
372 Some(ref expr) => quote! {
373 if #expr {
374 #data_file_key_quote
375 } else {
376 ""
377 }
378 },
379 None => quote! { "" },
380 };
381
382 let effect_quote = quote! {
383 if #initial_language_from_data_file_quote.is_empty() {
384 return;
385 }
386 if let Some(l) = ::leptos_fluent::data_file::get(
387 #initial_language_from_data_file_quote
388 ) {
389 lang = ::leptos_fluent::l(&l, &LANGUAGES);
390 }
391 };
392
393 match param.expr {
394 Some(ref expr) => {
395 let q = quote! {
396 if #expr && lang.is_none() {
397 #effect_quote
398 }
399 };
400 match param.exprpath {
401 Some(ref path) => quote!(#path{#q}),
402 None => q,
403 }
404 }
405 None => quote!(),
406 }
407 })
408 .collect();
409
410 #[cfg(all(not(feature = "system"), not(feature = "ssr")))]
411 let initial_language_from_data_file_quote = quote! {};
412
413 #[cfg(all(feature = "system", feature = "ssr"))]
414 {
415 _ = initial_language_from_data_file;
416 }
417
418 let initial_language_from_server_function_quote: proc_macro2::TokenStream = {
419 let set_to_cookie_quote: proc_macro2::TokenStream = {
420 let effect_quote = quote! {
421 ::leptos_fluent::cookie::set(
422 #cookie_name_quote,
423 &l.id.to_string(),
424 &#cookie_attrs_quote
425 );
426 };
427
428 initial_language_from_server_function_to_cookie
429 .iter()
430 .map(|param| match param.expr {
431 Some(ref expr) => {
432 let q = quote!(if #expr {#effect_quote});
433 match param.exprpath {
434 Some(ref path) => quote!(#path{#q}),
435 None => q,
436 }
437 }
438 None => quote!(),
439 })
440 .collect()
441 };
442
443 #[cfg(not(feature = "ssr"))]
444 let set_to_local_storage_quote: proc_macro2::TokenStream = {
445 let effect_quote = quote! {
446 ::leptos_fluent::local_storage::set(
447 #local_storage_key_quote,
448 &l.id.to_string()
449 );
450 };
451
452 initial_language_from_server_function_to_local_storage
453 .iter()
454 .map(|param| match param.expr {
455 Some(ref expr) => {
456 let q = quote!(if #expr {#effect_quote});
457 match param.exprpath {
458 Some(ref path) => quote!(#path{#q}),
459 None => q,
460 }
461 }
462 None => quote!(),
463 })
464 .collect()
465 };
466
467 #[cfg(feature = "ssr")]
468 let set_to_local_storage_quote = {
469 _ = initial_language_from_server_function_to_local_storage;
470
471 quote! {}
472 };
473
474 initial_language_from_server_function
475 .iter()
476 .map(|param| {
477 let ident = ¶m.expr;
478 let effect_quote = quote! {
479 ::leptos::task::spawn(async move {
480 let lang_result = #ident().await;
481 if let Ok(maybe_lang) = lang_result {
482 if let Some(l) = maybe_lang {
483 lang = ::leptos_fluent::l(&l, &LANGUAGES);
484 if let Some(l) = lang {
485 #set_to_cookie_quote
486 #set_to_local_storage_quote
487 }
488 }
489 }
490 });
491 };
492
493 match param.expr {
494 Some(_) => {
495 let quote = quote! {
496 if lang.is_none() {
497 #effect_quote
498 }
499 };
500 match param.exprpath {
501 Some(ref path) => quote!(#path{#quote}),
502 None => quote,
503 }
504 }
505 None => quote!(),
506 }
507 })
508 .collect()
509 };
510
511 let sync_language_with_server_function_quote: proc_macro2::TokenStream =
512 set_language_to_server_function.iter().map(|param| {
513 let ident = ¶m.expr;
514 let effect_quote = quote! {
515 ::leptos::prelude::Effect::new(move |_| {
516 ::leptos::task::spawn(async {
517 _ = #ident(#get_language_quote.id.to_string()).await;
518 });
519 });
520 };
521
522 match param.expr {
523 Some(_) => match param.exprpath {
524 Some(ref path) => quote! { #path{#effect_quote} },
525 None => effect_quote,
526 },
527 None => quote!(),
528 }
529 }).collect();
530
531 let initial_language_from_url_path_to_server_function_quote: proc_macro2::TokenStream =
532 initial_language_from_url_path_to_server_function.iter().map(|param| {
533 match param.expr {
534 Some(ref ident) => {
535 let quote = quote! {
536 ::leptos::task::spawn(async move {
537 _ = #ident(l.id.to_string()).await;
538 });
539 };
540 match param.exprpath {
541 Some(ref path) => quote!(#path{#quote}),
542 None => quote,
543 }
544 },
545 None => quote!(),
546 }
547 }).collect();
548
549 let initial_language_from_url_path_quote: proc_macro2::TokenStream = {
550 if let Some(ref ident) = url_path {
551 initial_language_from_url_path.iter().map(|param| {
552 #[cfg(not(feature = "ssr"))]
553 let effect_quote = {
554 let to_cookie_effect_quote: proc_macro2::TokenStream =
555 initial_language_from_url_path_to_cookie.iter().map(|param| {
556 let effect_quote = quote! {
557 ::leptos_fluent::cookie::set(
558 #cookie_name_quote,
559 &l.id.to_string(),
560 &#cookie_attrs_quote
561 );
562 };
563
564 match param.expr {
565 Some(ref expr) => {
566 let q = quote! {
567 if #expr {
568 #effect_quote
569 }
570 };
571 match param.exprpath {
572 Some(ref path) => quote!(#path{#q}),
573 None => q,
574 }
575 },
576 None => quote!(),
577 }
578 }).collect();
579
580 let to_local_storage_effect_quote: proc_macro2::TokenStream =
581 initial_language_from_url_path_to_local_storage.iter().map(|param| {
582 let effect_quote = quote! {
583 ::leptos_fluent::local_storage::set(
584 #local_storage_key_quote,
585 &l.id.to_string()
586 );
587 };
588
589 match param.expr {
590 Some(ref expr) => {
591 let q = quote! {
592 if #expr {
593 #effect_quote
594 }
595 };
596 match param.exprpath {
597 Some(ref path) => quote!(#path{#q}),
598 None => q,
599 }
600 },
601 None => quote!(),
602 }
603 }).collect();
604
605 let to_session_storage_effect_quote: proc_macro2::TokenStream =
606 initial_language_from_url_path_to_session_storage.iter().map(|param| {
607 let effect_quote = quote! {
608 ::leptos_fluent::session_storage::set(
609 #local_storage_key_quote,
610 &l.id.to_string()
611 );
612 };
613
614 match param.expr {
615 Some(ref expr) => {
616 let q = quote! {
617 if #expr {
618 #effect_quote
619 }
620 };
621 match param.exprpath {
622 Some(ref path) => quote!(#path{#q}),
623 None => q,
624 }
625 },
626 None => quote!(),
627 }
628 }).collect();
629
630 quote! {
631 if let Some(url_path) = ::leptos_fluent::url::path::get() {
632 lang = ::leptos_fluent::l(#ident(&url_path), &LANGUAGES);
633 if let Some(l) = lang {
634 #to_cookie_effect_quote
635 #to_local_storage_effect_quote
636 #to_session_storage_effect_quote
637 #initial_language_from_url_path_to_server_function_quote
638 }
639 }
640 }
641 };
642
643 #[cfg(all(feature = "ssr", feature = "actix"))]
644 let effect_quote = quote! {
645 if let Some(req) = ::leptos::prelude::use_context::<::leptos_actix::Request>() {
646 lang = ::leptos_fluent::l(#ident(&req.path()), &LANGUAGES);
647 if let Some(l) = lang {
648 #initial_language_from_url_path_to_server_function_quote
649 }
650 }
651 };
652
653 #[cfg(all(feature = "ssr", feature = "axum"))]
654 let effect_quote = quote! {
655 if let Some(req) = ::leptos::prelude::use_context::<::axum::http::request::Parts>() {
656 lang = ::leptos_fluent::l(#ident(&req.uri.path()), &LANGUAGES);
657 if let Some(l) = lang {
658 #initial_language_from_url_path_to_server_function_quote
659 }
660 }
661 };
662
663 #[cfg(all(feature = "ssr", not(feature = "axum"), not(feature = "actix")))]
664 let effect_quote = {
665 _ = initial_language_from_url_path_to_server_function_quote;
666 quote! {}
667 };
668
669 let quote = quote! {
670 if lang.is_none() {
671 #effect_quote
672 }
673 };
674
675 match param.exprpath {
676 Some(ref path) => quote! {
677 #path{#quote}
678 },
679 None => quote,
680 }
681 }).collect()
682 } else {
683 quote!()
684 }
685 };
686
687 let sync_html_tag_quote: proc_macro2::TokenStream = {
688 let sync_html_tag_lang_bool_quote: proc_macro2::TokenStream = {
692 let quote = sync_html_tag_lang
693 .iter()
694 .map(|param| match param.expr {
695 Some(ref expr) => {
696 let q = quote! { #expr };
697 match param.exprpath {
698 Some(ref path) => quote!(#path{#q}),
699 None => q,
700 }
701 }
702 None => quote! { false },
703 })
704 .collect::<proc_macro2::TokenStream>();
705
706 match quote.is_empty() {
707 true => quote! { false },
708 false => quote! { #quote },
709 }
710 };
711
712 let sync_html_tag_dir_bool_quote: proc_macro2::TokenStream = {
713 let quote = sync_html_tag_dir
714 .iter()
715 .map(|param| match param.expr {
716 Some(ref expr) => {
717 let q = quote! { #expr };
718 match param.exprpath {
719 Some(ref path) => quote!(#path{#q}),
720 None => q,
721 }
722 }
723 None => quote! { false },
724 })
725 .collect::<proc_macro2::TokenStream>();
726
727 match quote.is_empty() {
728 true => quote! { false },
729 false => quote! { #quote },
730 }
731 };
732
733 let attr_lang_quote =
734 match sync_html_tag_lang_bool_quote.to_string() == "false" {
735 true => quote! {},
736 false => {
737 quote! { attr:lang=|| {#get_language_quote.id.to_string()} }
738 }
739 };
740 let attr_dir_quote = match sync_html_tag_dir_bool_quote.to_string()
741 == "false"
742 {
743 true => quote! {},
744 false => quote! { attr:dir=|| {#get_language_quote.dir.as_str()} },
745 };
746
747 match attr_lang_quote.is_empty() && attr_dir_quote.is_empty() {
748 true => quote! {},
749 false => quote! {{
750 use ::leptos_fluent::__reexports::leptos_meta::{provide_meta_context, Html};
751 provide_meta_context();
752 ::leptos::prelude::view! {
753 <Html #attr_lang_quote #attr_dir_quote/>
754 }
755 }},
756 }
757 };
758
759 let url_param_quote = match url_param.lit {
760 Some(ref lit) => quote! { #lit },
761 None => match url_param.expr {
762 Some(ref expr) => quote! { #expr },
763 None => quote! { "lang" },
764 },
765 };
766
767 #[cfg(not(feature = "ssr"))]
768 let sync_language_with_local_storage_quote: proc_macro2::TokenStream = {
769 let effect_quote = quote! {
770 ::leptos::prelude::Effect::new(move |_| {
771 ::leptos_fluent::local_storage::set(
772 #local_storage_key_quote,
773 &#get_language_quote.id.to_string()
774 );
775 });
776 };
777
778 set_language_to_local_storage
779 .iter()
780 .map(|param| match param.expr {
781 Some(ref expr) => {
782 let q = quote! {
783 if #expr {
784 #effect_quote
785 }
786 };
787 match param.exprpath {
788 Some(ref path) => quote!(#path{#q}),
789 None => q,
790 }
791 }
792 None => quote!(),
793 })
794 .collect()
795 };
796
797 #[cfg(feature = "ssr")]
798 let sync_language_with_local_storage_quote = quote!();
799
800 #[cfg(not(feature = "ssr"))]
801 let sync_language_with_session_storage_quote: proc_macro2::TokenStream = {
802 let effect_quote = quote! {
803 ::leptos::prelude::Effect::new(move |_| {
804 ::leptos_fluent::session_storage::set(
805 #session_storage_key_quote,
806 &#get_language_quote.id.to_string()
807 );
808 });
809 };
810
811 set_language_to_session_storage
812 .iter()
813 .map(|param| match param.expr {
814 Some(ref expr) => {
815 let q = quote! {
816 if #expr {
817 #effect_quote
818 }
819 };
820 match param.exprpath {
821 Some(ref path) => quote!(#path{#q}),
822 None => q,
823 }
824 }
825 None => quote!(),
826 })
827 .collect()
828 };
829
830 #[cfg(feature = "ssr")]
831 let sync_language_with_session_storage_quote = quote!();
832
833 let initial_language_from_url_param_quote: proc_macro2::TokenStream = {
834 #[cfg(all(feature = "hydrate", not(feature = "ssr")))]
835 let hydrate_rerender_quote = quote! {
836 ::leptos::prelude::Effect::new(move |prev: Option<()>| {
837 if prev.is_none() {
838 #set_language_quote;
839 }
840 });
841 };
842
843 #[cfg(all(not(feature = "hydrate"), not(feature = "ssr")))]
844 let hydrate_rerender_quote = quote! {};
845
846 #[cfg(not(feature = "ssr"))]
847 let set_to_local_storage_quote: proc_macro2::TokenStream = {
848 let effect_quote = quote! {
849 ::leptos_fluent::local_storage::set(
850 #local_storage_key_quote,
851 &l.id.to_string()
852 );
853 };
854
855 initial_language_from_url_param_to_local_storage
856 .iter()
857 .map(|param| match param.expr {
858 Some(ref expr) => {
859 let q = quote!(if #expr {#effect_quote});
860 match param.exprpath {
861 Some(ref path) => quote!(#path{#q}),
862 None => q,
863 }
864 }
865 None => quote!(),
866 })
867 .collect()
868 };
869
870 #[cfg(not(feature = "ssr"))]
871 let set_to_session_storage_quote: proc_macro2::TokenStream = {
872 let effect_quote = quote! {
873 ::leptos_fluent::session_storage::set(
874 #session_storage_key_quote,
875 &l.id.to_string()
876 );
877 };
878
879 initial_language_from_url_param_to_session_storage
880 .iter()
881 .map(|param| match param.expr {
882 Some(ref expr) => {
883 let q = quote!(if #expr {#effect_quote});
884 match param.exprpath {
885 Some(ref path) => quote!(#path{#q}),
886 None => q,
887 }
888 }
889 None => quote!(),
890 })
891 .collect()
892 };
893
894 #[cfg(not(feature = "ssr"))]
895 let set_to_cookie_quote: proc_macro2::TokenStream = {
896 let effect_quote = quote! {
897 ::leptos_fluent::cookie::set(
898 #cookie_name_quote,
899 &l.id.to_string(),
900 &#cookie_attrs_quote
901 );
902 };
903
904 initial_language_from_url_param_to_cookie
905 .iter()
906 .map(|param| match param.expr {
907 Some(ref expr) => {
908 let q = quote!(if #expr {#effect_quote});
909 match param.exprpath {
910 Some(ref path) => quote!(#path{#q}),
911 None => q,
912 }
913 }
914 None => quote!(),
915 })
916 .collect()
917 };
918
919 #[cfg(feature = "ssr")]
920 {
921 _ = initial_language_from_url_param_to_local_storage;
922 _ = initial_language_from_url_param_to_session_storage;
923 _ = initial_language_from_url_param_to_cookie;
924 }
925
926 let set_to_server_function_quote: proc_macro2::TokenStream =
927 initial_language_from_url_param_to_server_function
928 .iter()
929 .map(|param| match param.expr {
930 Some(ref ident) => {
931 let quote = quote! {
932 ::leptos::task::spawn(async move {
933 _ = #ident(l.id.to_string()).await;
934 });
935 };
936 match param.exprpath {
937 Some(ref path) => quote!(#path{#quote}),
938 None => quote,
939 }
940 }
941 None => quote!(),
942 })
943 .collect();
944
945 #[cfg(not(feature = "ssr"))]
946 let parse_language_quote = quote! {
947 if let Some(l) = ::leptos_fluent::url::param::get(#url_param_quote) {
948 lang = ::leptos_fluent::l(&l, &LANGUAGES);
949 if let Some(l) = lang {
950 #hydrate_rerender_quote
951 #set_to_local_storage_quote
952 #set_to_session_storage_quote
953 #set_to_cookie_quote
954 #set_to_server_function_quote
955 }
956 }
957 };
958
959 #[cfg(all(feature = "ssr", any(feature = "actix", feature = "axum")))]
960 let lang_parser_quote = quote! {
961 let mut maybe_lang = None;
962 for (key, value) in uri_query.split('&').map(|pair| {
963 let mut split = pair.splitn(2, '=');
964 (split.next().unwrap_or(""), split.next().unwrap_or(""))
965 }) {
966 if key == #url_param_quote {
967 maybe_lang = Some(value);
968 break;
969 }
970 }
971
972 if let Some(l) = maybe_lang {
973 lang = ::leptos_fluent::l(&l, &LANGUAGES);
974 if let Some(l) = lang {
975 #set_to_server_function_quote
976 }
977 }
978 };
979
980 #[cfg(all(feature = "ssr", feature = "actix"))]
981 let parse_language_quote = quote! {
982 if let Some(req) = ::leptos::prelude::use_context::<::leptos_actix::Request>() {
983 let uri_query = req.uri().query().unwrap_or("");
984 #lang_parser_quote
985 }
986 };
987
988 #[cfg(all(feature = "ssr", feature = "axum"))]
989 let parse_language_quote = quote! {
990 if let Some(req) = ::leptos::prelude::use_context::<::axum::http::request::Parts>() {
991 let uri_query = req.uri.query().unwrap_or("");
992 #lang_parser_quote
993 }
994 };
995
996 #[cfg(all(
998 feature = "ssr",
999 not(feature = "actix"),
1000 not(feature = "axum"),
1001 ))]
1002 let parse_language_quote = quote! {};
1003
1004 initial_language_from_url_param
1005 .iter()
1006 .map(|param| match param.expr {
1007 Some(ref expr) => match parse_language_quote.is_empty() {
1008 true => quote!(),
1009 false => {
1010 let q = quote! {
1011 if #expr {
1012 #parse_language_quote
1013 }
1014 };
1015 match param.exprpath {
1016 Some(ref path) => quote!(#path{#q}),
1017 None => q,
1018 }
1019 }
1020 },
1021 None => quote!(),
1022 })
1023 .collect()
1024 };
1025
1026 #[cfg(not(feature = "ssr"))]
1027 let initial_language_from_local_storage_quote: proc_macro2::TokenStream = {
1028 let set_cookie_quote = quote! {
1029 ::leptos_fluent::cookie::set(
1030 #cookie_name_quote,
1031 &l.id.to_string(),
1032 &#cookie_attrs_quote
1033 );
1034 };
1035
1036 let initial_language_from_local_storage_to_cookie_quote: proc_macro2::TokenStream =
1037 initial_language_from_local_storage_to_cookie.iter().map(|param| {
1038 match param.expr {
1039 Some(ref expr) => {
1040 let q = quote! {
1041 if #expr {
1042 #set_cookie_quote
1043 }
1044 };
1045 match param.exprpath {
1046 Some(ref path) => quote!(#path{#q}),
1047 None => q,
1048 }
1049 },
1050 None => quote!(),
1051 }
1052 }).collect();
1053
1054 let set_session_storage_quote = quote! {
1055 ::leptos_fluent::session_storage::set(
1056 #session_storage_key_quote,
1057 &l.id.to_string()
1058 );
1059 };
1060
1061 let initial_language_from_local_storage_to_session_storage_quote: proc_macro2::TokenStream =
1062 initial_language_from_local_storage_to_session_storage.iter().map(|param| {
1063 match param.expr {
1064 Some(ref expr) => {
1065 let q = quote! {
1066 if #expr {
1067 #set_session_storage_quote
1068 }
1069 };
1070 match param.exprpath {
1071 Some(ref path) => quote!(#path{#q}),
1072 None => q,
1073 }
1074 },
1075 None => quote!(),
1076 }
1077 }).collect();
1078
1079 let initial_language_from_local_storage_to_server_function_quote: proc_macro2::TokenStream =
1080 initial_language_from_local_storage_to_server_function.iter().map(|param| {
1081 match param.expr {
1082 Some(ref ident) => {
1083 let quote = quote! {
1084 ::leptos::task::spawn(async move {
1085 _ = #ident(l.id.to_string()).await;
1086 });
1087 };
1088 match param.exprpath {
1089 Some(ref path) => quote!(#path{#quote}),
1090 None => quote,
1091 }
1092 },
1093 None => quote!(),
1094 }
1095 }).collect();
1096
1097 let local_storage_get_quote = quote! {
1098 if let Some(l) = ::leptos_fluent::local_storage::get(#local_storage_key_quote)
1099 {
1100 lang = ::leptos_fluent::l(&l, &LANGUAGES);
1101 if let Some(l) = lang {
1102 #initial_language_from_local_storage_to_cookie_quote
1103 #initial_language_from_local_storage_to_session_storage_quote
1104 #initial_language_from_local_storage_to_server_function_quote
1105 }
1106 }
1107 };
1108
1109 initial_language_from_local_storage
1110 .iter()
1111 .map(|param| match param.expr {
1112 Some(ref expr) => {
1113 let q = quote! {
1114 if #expr && lang.is_none() {
1115 #local_storage_get_quote
1116 }
1117 };
1118 match param.exprpath {
1119 Some(ref path) => quote!(#path{#q}),
1120 None => q,
1121 }
1122 }
1123 None => quote!(),
1124 })
1125 .collect()
1126 };
1127
1128 #[cfg(not(feature = "ssr"))]
1129 let initial_language_from_session_storage_quote: proc_macro2::TokenStream = {
1130 let set_cookie_quote = quote! {
1131 ::leptos_fluent::cookie::set(
1132 #cookie_name_quote,
1133 &l.id.to_string(),
1134 &#cookie_attrs_quote
1135 );
1136 };
1137
1138 let initial_language_from_session_storage_to_cookie_quote: proc_macro2::TokenStream =
1139 initial_language_from_session_storage_to_cookie.iter().map(|param| {
1140 match param.expr {
1141 Some(ref expr) => {
1142 let q = quote! {
1143 if #expr {
1144 #set_cookie_quote
1145 }
1146 };
1147 match param.exprpath {
1148 Some(ref path) => quote!(#path{#q}),
1149 None => q,
1150 }
1151 },
1152 None => quote!(),
1153 }
1154 }).collect();
1155
1156 let set_local_storage_quote = quote! {
1157 ::leptos_fluent::local_storage::set(
1158 #local_storage_key_quote,
1159 &l.id.to_string()
1160 );
1161 };
1162
1163 let initial_language_from_session_storage_to_local_storage_quote: proc_macro2::TokenStream =
1164 initial_language_from_session_storage_to_local_storage.iter().map(|param| {
1165 match param.expr {
1166 Some(ref expr) => {
1167 let q = quote! {
1168 if #expr {
1169 #set_local_storage_quote
1170 }
1171 };
1172 match param.exprpath {
1173 Some(ref path) => quote!(#path{#q}),
1174 None => q,
1175 }
1176 },
1177 None => quote!(),
1178 }
1179 }).collect();
1180
1181 let initial_language_from_session_storage_to_server_function_quote: proc_macro2::TokenStream =
1182 initial_language_from_session_storage_to_server_function.iter().map(|param| {
1183 match param.expr {
1184 Some(ref ident) => {
1185 let quote = quote! {
1186 ::leptos::task::spawn(async move {
1187 _ = #ident(l.id.to_string()).await;
1188 });
1189 };
1190 match param.exprpath {
1191 Some(ref path) => quote!(#path{#quote}),
1192 None => quote,
1193 }
1194 },
1195 None => quote!(),
1196 }
1197 }).collect();
1198
1199 let session_storage_get_quote = quote! {
1200 if let Some(l) = ::leptos_fluent::session_storage::get(#session_storage_key_quote)
1201 {
1202 lang = ::leptos_fluent::l(&l, &LANGUAGES);
1203 if let Some(l) = lang {
1204 #initial_language_from_session_storage_to_cookie_quote
1205 #initial_language_from_session_storage_to_local_storage_quote
1206 #initial_language_from_session_storage_to_server_function_quote
1207 }
1208 }
1209 };
1210
1211 initial_language_from_session_storage
1212 .iter()
1213 .map(|param| match param.expr {
1214 Some(ref expr) => {
1215 let q = quote! {
1216 if #expr && lang.is_none() {
1217 #session_storage_get_quote
1218 }
1219 };
1220 match param.exprpath {
1221 Some(ref path) => quote!(#path{#q}),
1222 None => q,
1223 }
1224 }
1225 None => quote!(),
1226 })
1227 .collect()
1228 };
1229
1230 #[cfg(feature = "ssr")]
1231 {
1232 _ = initial_language_from_local_storage;
1233 _ = initial_language_from_local_storage_to_cookie;
1234 _ = initial_language_from_local_storage_to_session_storage;
1235 _ = initial_language_from_local_storage_to_server_function;
1236 _ = initial_language_from_session_storage;
1237 _ = initial_language_from_session_storage_to_cookie;
1238 _ = initial_language_from_session_storage_to_local_storage;
1239 _ = initial_language_from_session_storage_to_server_function;
1240 }
1241
1242 let sync_language_with_url_param_quote: proc_macro2::TokenStream = {
1243 let effect_quote = quote! {
1244 ::leptos::prelude::Effect::new(move |_| {
1245 ::leptos_fluent::url::param::set(
1246 #url_param_quote,
1247 &#get_language_quote.id.to_string()
1248 );
1249 });
1250 };
1251
1252 set_language_to_url_param
1253 .iter()
1254 .map(|param| match param.expr {
1255 Some(ref expr) => {
1256 let q = quote! {
1257 if #expr {
1258 #effect_quote
1259 }
1260 };
1261 match param.exprpath {
1262 Some(ref path) => quote!(#path{#q}),
1263 None => q,
1264 }
1265 }
1266 None => quote!(),
1267 })
1268 .collect()
1269 };
1270
1271 #[cfg(not(feature = "ssr"))]
1272 let initial_language_from_navigator_quote: proc_macro2::TokenStream = {
1273 let initial_language_from_navigator_to_local_storage_quote: proc_macro2::TokenStream = {
1274 let effect_quote = quote! {
1275 ::leptos_fluent::local_storage::set(
1276 #local_storage_key_quote,
1277 &l.id.to_string()
1278 );
1279 };
1280
1281 initial_language_from_navigator_to_local_storage.iter().map(|param| {
1282 match param.expr {
1283 Some(ref expr) => {
1284 let q = quote!(if #expr {#effect_quote});
1285 match param.exprpath {
1286 Some(ref path) => quote!(#path{#q}),
1287 None => q,
1288 }
1289 },
1290 None => quote!(),
1291 }
1292 }).collect()
1293 };
1294
1295 let initial_language_from_navigator_to_session_storage_quote: proc_macro2::TokenStream = {
1296 let effect_quote = quote! {
1297 ::leptos_fluent::session_storage::set(
1298 #session_storage_key_quote,
1299 &l.id.to_string()
1300 );
1301 };
1302
1303 initial_language_from_navigator_to_session_storage.iter().map(|param| {
1304 match param.expr {
1305 Some(ref expr) => {
1306 let q = quote!(if #expr {#effect_quote});
1307 match param.exprpath {
1308 Some(ref path) => quote!(#path{#q}),
1309 None => q,
1310 }
1311 },
1312 None => quote!(),
1313 }
1314 }).collect()
1315 };
1316
1317 let initial_language_from_navigator_to_cookie_quote: proc_macro2::TokenStream = {
1318 let effect_quote = quote! {
1319 ::leptos_fluent::cookie::set(
1320 #cookie_name_quote,
1321 &l.id.to_string(),
1322 &#cookie_attrs_quote
1323 );
1324 };
1325
1326 initial_language_from_navigator_to_cookie.iter().map(|param| {
1327 match param.expr {
1328 Some(ref expr) => {
1329 let q = quote!(if #expr {#effect_quote});
1330 match param.exprpath {
1331 Some(ref path) => quote!(#path{#q}),
1332 None => q,
1333 }
1334 },
1335 None => quote!(),
1336 }
1337 }).collect()
1338 };
1339
1340 let initial_language_from_navigator_to_server_function_quote: proc_macro2::TokenStream =
1341 initial_language_from_navigator_to_server_function.iter().map(|param| {
1342 match param.expr {
1343 Some(ref ident) => {
1344 let quote = quote! {
1345 ::leptos::task::spawn(async move {
1346 _ = #ident(l.id.to_string()).await;
1347 });
1348 };
1349 match param.exprpath {
1350 Some(ref path) => quote!(#path{#quote}),
1351 None => quote,
1352 }
1353 },
1354 None => quote!(),
1355 }
1356 }).collect();
1357
1358 let window_navigator_languages_quote = quote! {
1359 let languages = ::leptos::prelude::window().navigator().languages().to_vec();
1360 for raw_language in languages {
1361 let language = raw_language.as_string();
1362 if language.is_none() {
1363 continue;
1364 }
1365 lang = ::leptos_fluent::l(&language.unwrap(), &LANGUAGES);
1366 if let Some(l) = lang {
1367 #initial_language_from_navigator_to_local_storage_quote
1368 #initial_language_from_navigator_to_session_storage_quote
1369 #initial_language_from_navigator_to_cookie_quote
1370 #initial_language_from_navigator_to_server_function_quote
1371 break;
1372 }
1373 }
1374 };
1375
1376 initial_language_from_navigator
1377 .iter()
1378 .map(|param| match param.expr {
1379 Some(ref expr) => {
1380 let q = quote! {
1381 if #expr && lang.is_none() {
1382 #window_navigator_languages_quote
1383 }
1384 };
1385 match param.exprpath {
1386 Some(ref path) => quote!(#path{#q}),
1387 None => q,
1388 }
1389 }
1390 None => quote!(),
1391 })
1392 .collect()
1393 };
1394
1395 #[cfg(feature = "ssr")]
1396 {
1397 _ = initial_language_from_navigator;
1398 _ = initial_language_from_navigator_to_local_storage;
1399 _ = initial_language_from_navigator_to_cookie;
1400 _ = initial_language_from_navigator_to_server_function;
1401 }
1402
1403 let set_language_from_navigator_quote: proc_macro2::TokenStream = {
1404 #[cfg(not(feature = "ssr"))]
1405 {
1406 #[cfg(feature = "debug")]
1407 let log_language_quote = quote! {
1408 ::leptos::logging::log!("[leptos-fluent/debug] Language changed to {:?}", &l);
1409 };
1410
1411 #[cfg(not(feature = "debug"))]
1412 let log_language_quote = quote!();
1413
1414 let effect_quote = quote! {
1415 use ::leptos_fluent::__reexports::wasm_bindgen::JsCast;
1416 let closure: Box<dyn FnMut(_)> = Box::new(
1417 move |_: ::leptos_fluent::__reexports::web_sys::Window| {
1418 let languages = ::leptos::prelude::window().navigator().languages().to_vec();
1419 for raw_language in languages {
1420 let language = raw_language.as_string();
1421 if language.is_none() {
1422 continue;
1423 }
1424 let l = ::leptos_fluent::l(&language.unwrap(), &LANGUAGES);
1425 #log_language_quote
1426 if let Some(l) = l {
1427 #set_language_quote;
1428 break;
1429 }
1430 }
1431 }
1432 );
1433 let cb = ::leptos_fluent::__reexports::wasm_bindgen::closure::Closure::wrap(
1434 closure
1435 );
1436 ::leptos::prelude::window().add_event_listener_with_callback(
1437 "languagechange",
1438 cb.as_ref().unchecked_ref()
1439 ).expect("Failed to add event listener for window languagechange");
1440 cb.forget();
1441 };
1442
1443 set_language_from_navigator
1444 .iter()
1445 .map(|param| match param.expr {
1446 Some(ref expr) => {
1447 let q = quote!(if #expr {#effect_quote});
1448 match param.exprpath {
1449 Some(ref path) => quote!(#path{#q}),
1450 None => q,
1451 }
1452 }
1453 None => quote!(),
1454 })
1455 .collect()
1456 }
1457
1458 #[cfg(feature = "ssr")]
1459 {
1460 _ = set_language_from_navigator;
1461 quote!()
1462 }
1463 };
1464
1465 #[cfg(all(feature = "actix", feature = "ssr"))]
1468 let initial_language_from_accept_language_header_quote: proc_macro2::TokenStream = {
1469 let effect_quote = quote! {
1470 if let Some(req) = ::leptos::prelude::use_context::<::leptos_actix::Request>() {
1471 let maybe_header = req
1472 .headers()
1473 .get(::actix_web::http::header::ACCEPT_LANGUAGE)
1474 .and_then(|header| header.to_str().ok());
1475
1476 if let Some(header) = maybe_header {
1477 let langs = ::leptos_fluent::http_header::parse(header);
1478 for l in langs {
1479 if let Some(l) = ::leptos_fluent::l(&l, &LANGUAGES) {
1480 lang = Some(l);
1481 break;
1482 }
1483 }
1484 }
1485 }
1486 };
1487
1488 initial_language_from_accept_language_header.iter().map(|param| {
1489 match param.expr {
1490 Some(ref expr) => {
1491 let q = quote! {
1492 if #expr && lang.is_none() {
1493 #effect_quote
1494 }
1495 };
1496 match param.exprpath {
1497 Some(ref path) => quote!(#path{#q}),
1498 None => q,
1499 }
1500 },
1501 None => quote!(),
1502 }
1503 }).collect()
1504 };
1505
1506 #[cfg(all(feature = "axum", feature = "ssr"))]
1508 let initial_language_from_accept_language_header_quote: proc_macro2::TokenStream = {
1509 let effect_quote = quote! {
1510 if let Some(req) = ::leptos::prelude::use_context::<::axum::http::request::Parts>() {
1511 let maybe_header = req
1512 .headers
1513 .get(::axum::http::header::ACCEPT_LANGUAGE)
1514 .and_then(|header| header.to_str().ok());
1515
1516 if let Some(header) = maybe_header {
1517 let langs = ::leptos_fluent::http_header::parse(header);
1518 for l in langs {
1519 if let Some(l) = ::leptos_fluent::l(&l, &LANGUAGES) {
1520 lang = Some(l);
1521 break;
1522 }
1523 }
1524 }
1525 }
1526 };
1527
1528 initial_language_from_accept_language_header.iter().map(|param| {
1529 match param.expr {
1530 Some(ref expr) => {
1531 let q = quote! {
1532 if #expr && lang.is_none() {
1533 #effect_quote
1534 }
1535 };
1536 match param.exprpath {
1537 Some(ref path) => quote!(#path{#q}),
1538 None => q,
1539 }
1540 },
1541 None => quote!(),
1542 }
1543 }).collect()
1544 };
1545
1546 #[cfg(all(not(feature = "actix"), not(feature = "axum"), feature = "ssr"))]
1548 let initial_language_from_accept_language_header_quote = quote! {};
1549
1550 #[cfg(not(feature = "ssr"))]
1551 {
1552 _ = initial_language_from_accept_language_header;
1553 }
1554
1555 let initial_language_from_cookie_to_server_function_quote: proc_macro2::TokenStream =
1557 initial_language_from_cookie_to_server_function.iter().map(|param| {
1558 match param.expr {
1559 Some(ref ident) => {
1560 let quote = quote! {
1561 ::leptos::task::spawn(async move {
1562 _ = #ident(l.id.to_string()).await;
1563 });
1564 };
1565 match param.exprpath {
1566 Some(ref path) => quote!(#path{#quote}),
1567 None => quote,
1568 }
1569 },
1570 None => quote!(),
1571 }
1572 }).collect();
1573
1574 #[cfg(not(feature = "ssr"))]
1575 let initial_language_from_cookie_quote: proc_macro2::TokenStream = {
1576 let initial_language_from_cookie_to_local_storage_quote: proc_macro2::TokenStream = {
1577 let effect_quote = quote! {
1578 ::leptos_fluent::local_storage::set(
1579 #local_storage_key_quote,
1580 &l.id.to_string()
1581 );
1582 };
1583
1584 initial_language_from_cookie_to_local_storage.iter().map(|param| {
1585 match param.expr {
1586 Some(ref expr) => {
1587 let q = quote!(if #expr {#effect_quote});
1588 match param.exprpath {
1589 Some(ref path) => quote!(#path{#q}),
1590 None => q,
1591 }
1592 },
1593 None => quote!(),
1594 }
1595 }).collect()
1596 };
1597
1598 let initial_language_from_cookie_to_session_storage_quote: proc_macro2::TokenStream = {
1599 let effect_quote = quote! {
1600 ::leptos_fluent::session_storage::set(
1601 #session_storage_key_quote,
1602 &l.id.to_string()
1603 );
1604 };
1605
1606 initial_language_from_cookie_to_session_storage.iter().map(|param| {
1607 match param.expr {
1608 Some(ref expr) => {
1609 let q = quote!(if #expr {#effect_quote});
1610 match param.exprpath {
1611 Some(ref path) => quote!(#path{#q}),
1612 None => q,
1613 }
1614 },
1615 None => quote!(),
1616 }
1617 }).collect()
1618 };
1619
1620 let parse_client_cookie_quote = quote! {
1621 if let Some(cookie) = ::leptos_fluent::cookie::get(#cookie_name_quote) {
1622 if let Some(l) = ::leptos_fluent::l(&cookie, &LANGUAGES) {
1623 lang = Some(l);
1624 #initial_language_from_cookie_to_local_storage_quote
1625 #initial_language_from_cookie_to_session_storage_quote
1626 #initial_language_from_cookie_to_server_function_quote
1627 }
1628 }
1629 };
1630
1631 initial_language_from_cookie
1632 .iter()
1633 .map(|param| match param.expr {
1634 Some(ref expr) => {
1635 let q = quote! {
1636 if #expr && lang.is_none() {
1637 #parse_client_cookie_quote
1638 }
1639 };
1640 match param.exprpath {
1641 Some(ref path) => quote!(#path{#q}),
1642 None => q,
1643 }
1644 }
1645 None => quote!(),
1646 })
1647 .collect()
1648 };
1649
1650 #[cfg(not(feature = "ssr"))]
1651 let sync_language_with_cookie_quote: proc_macro2::TokenStream = {
1652 let effect_quote = quote! {
1653 ::leptos::prelude::Effect::new(move |_| {
1654 ::leptos_fluent::cookie::set(
1655 #cookie_name_quote,
1656 &#get_language_quote.id.to_string(),
1657 &#cookie_attrs_quote
1658 );
1659 });
1660 };
1661
1662 set_language_to_cookie
1663 .iter()
1664 .map(|param| match param.expr {
1665 Some(ref expr) => {
1666 let q = quote! {
1667 if #expr {
1668 #effect_quote
1669 }
1670 };
1671 match param.exprpath {
1672 Some(ref path) => quote!(#path{#q}),
1673 None => q,
1674 }
1675 }
1676 None => quote!(),
1677 })
1678 .collect()
1679 };
1680
1681 #[cfg(feature = "ssr")]
1682 {
1683 _ = initial_language_from_cookie;
1684 _ = initial_language_from_cookie_to_local_storage;
1685 _ = initial_language_from_cookie_to_session_storage;
1686 _ = cookie_attrs;
1687 _ = set_language_to_cookie;
1688 }
1689
1690 #[cfg(all(feature = "ssr", feature = "actix"))]
1692 let initial_language_from_cookie_quote: proc_macro2::TokenStream = {
1693 let effect_quote = quote! {
1694 if let Some(req) = ::leptos::prelude::use_context::<::leptos_actix::Request>() {
1695 let maybe_cookie = req
1696 .cookie(#cookie_name_quote)
1697 .and_then(|cookie| Some(cookie.value().to_string()));
1698
1699 if let Some(cookie) = maybe_cookie {
1700 if let Some(l) = ::leptos_fluent::l(&cookie, &LANGUAGES) {
1701 lang = Some(l);
1702 #initial_language_from_cookie_to_server_function_quote
1703 }
1704 }
1705 }
1706 };
1707
1708 initial_language_from_cookie
1709 .iter()
1710 .map(|param| match param.expr {
1711 Some(ref expr) => {
1712 let q = quote! {
1713 if #expr && lang.is_none() {
1714 #effect_quote
1715 }
1716 };
1717 match param.exprpath {
1718 Some(ref path) => quote!(#path{#q}),
1719 None => q,
1720 }
1721 }
1722 None => quote!(),
1723 })
1724 .collect()
1725 };
1726
1727 #[cfg(all(feature = "ssr", feature = "actix"))]
1729 let sync_language_with_cookie_quote = quote! {};
1730
1731 #[cfg(all(feature = "ssr", feature = "axum"))]
1733 let initial_language_from_cookie_quote: proc_macro2::TokenStream = {
1734 let effect_quote = quote! {
1735 if let Some(req) = ::leptos::prelude::use_context::<::axum::http::request::Parts>() {
1736 let maybe_cookie = req
1737 .headers
1738 .get(::axum::http::header::COOKIE)
1739 .and_then(|header| header.to_str().ok())
1740 .and_then(|cookie| {
1741 let cookie = cookie.split(';').find(|c| c.trim_start().starts_with(#cookie_name_quote));
1742 cookie.map(|c| c.split('=').nth(1).unwrap().trim_start().to_string())
1743 });
1744
1745 if let Some(cookie) = maybe_cookie {
1746 if let Some(l) = ::leptos_fluent::l(&cookie, &LANGUAGES) {
1747 lang = Some(l);
1748 #initial_language_from_cookie_to_server_function_quote
1749 }
1750 }
1751 }
1752 };
1753
1754 initial_language_from_cookie
1755 .iter()
1756 .map(|param| match param.expr {
1757 Some(ref expr) => {
1758 let q = quote! {
1759 if #expr && lang.is_none() {
1760 #effect_quote
1761 }
1762 };
1763 match param.exprpath {
1764 Some(ref path) => quote!(#path{#q}),
1765 None => q,
1766 }
1767 }
1768 None => quote!(),
1769 })
1770 .collect()
1771 };
1772
1773 #[cfg(all(feature = "ssr", feature = "axum"))]
1775 let sync_language_with_cookie_quote = quote! {};
1776
1777 #[cfg(all(not(feature = "actix"), not(feature = "axum"), feature = "ssr"))]
1779 let initial_language_from_cookie_quote = quote! {};
1780 #[cfg(all(
1781 not(feature = "actix"),
1782 not(feature = "axum"),
1783 feature = "ssr"
1784 ))]
1785 {
1786 _ = initial_language_from_cookie_to_server_function;
1787 };
1788
1789 #[cfg(all(not(feature = "actix"), not(feature = "axum"), feature = "ssr"))]
1790 let sync_language_with_cookie_quote = quote! {};
1791
1792 let initial_language_quote = {
1793 #[cfg(not(feature = "ssr"))]
1794 quote! {
1795 #initial_language_from_server_function_quote
1796 #initial_language_from_data_file_quote
1797 #initial_language_from_system_quote
1798 #initial_language_from_url_param_quote
1799 #initial_language_from_url_path_quote
1800 #initial_language_from_cookie_quote
1801 #initial_language_from_local_storage_quote
1802 #initial_language_from_session_storage_quote
1803 #initial_language_from_navigator_quote
1804 }
1805
1806 #[cfg(feature = "ssr")]
1807 quote! {
1808 #initial_language_from_server_function_quote
1809 #initial_language_from_url_param_quote
1810 #initial_language_from_url_path_quote
1811 #initial_language_from_cookie_quote
1812 #initial_language_from_accept_language_header_quote
1813 }
1814 };
1815
1816 let leptos_fluent_provide_meta_context_quote: proc_macro2::TokenStream = {
1817 let maybe_litstr_param =
1818 |lit: &Option<String>| -> proc_macro2::TokenStream {
1819 match lit {
1820 Some(ref lit) => quote! { #lit },
1821 None => quote! { None },
1822 }
1823 };
1824
1825 let maybe_some_litstr_param =
1826 |lit: &Option<String>| -> proc_macro2::TokenStream {
1827 match lit {
1828 Some(ref lit) => quote! { Some(#lit) },
1829 None => quote! { None },
1830 }
1831 };
1832
1833 let litstr_or_default = |lit: &Option<syn::LitStr>,
1834 expr: &Option<TokenStreamStr>,
1835 default_: &'static str|
1836 -> proc_macro2::TokenStream {
1837 match lit {
1838 Some(ref lit) => quote! { #lit },
1839 None => match expr {
1840 Some(ref expr) => expr.into_token_stream(),
1841 None => quote! { #default_ },
1842 },
1843 }
1844 };
1845
1846 let lit_bool_expr_or_idents =
1847 |params: &[LitBoolExprOrIdent]| -> proc_macro2::TokenStream {
1848 if params.is_empty() {
1849 return quote! { false };
1850 }
1851
1852 params
1853 .iter()
1854 .map(|param| {
1855 let quote = match ¶m.expr {
1856 Some(ident) => match ident
1857 .to_token_stream()
1858 .to_string()
1859 .as_str()
1860 {
1861 "false" => quote! { false },
1862 _ => quote! { true },
1863 },
1864 None => quote! { false },
1865 };
1866
1867 match param.exprpath {
1868 Some(ref path) => quote!(#path{#quote}),
1869 None => quote,
1870 }
1871 })
1872 .collect()
1873 };
1874
1875 let maybe_some_litbool_or_litstr_param =
1876 |param: &Option<LitBoolOrStr>| {
1877 match param {
1878 Some(LitBoolOrStr::Bool(lit_bool)) => quote!(#lit_bool),
1879 Some(LitBoolOrStr::Str(_)) => quote!(true), None => quote!(None),
1881 }
1882 };
1883
1884 provide_meta_context.iter().map(|param| {
1885 match param.lit.unwrap_or(false) {
1886 true => {
1887 let core_locales_quote = maybe_litstr_param(&core_locales_path);
1888 let default_language_quote = match &default_language {
1889 Some(ref lang, ..) => {
1890 let code = &lang.0;
1891 quote!(Some(#code))
1892 },
1893 None => quote!(None)
1894 };
1895 let languages_quote =
1896 maybe_some_litstr_param(&raw_languages_path);
1897 let translations_quote = if translations.is_some() {
1898 quote!(true)
1899 } else {
1900 quote!(false)
1901 };
1902 let check_translations_quote =
1903 maybe_some_litbool_or_litstr_param(&check_translations);
1904 let fill_translations_quote =
1905 maybe_some_litstr_param(&fill_translations);
1906 let sync_html_tag_lang_quote =
1907 lit_bool_expr_or_idents(&sync_html_tag_lang);
1908 let sync_html_tag_dir_quote =
1909 lit_bool_expr_or_idents(&sync_html_tag_dir);
1910 let url_param_quote =
1911 litstr_or_default(&url_param.lit, &url_param.expr, "lang");
1912 let initial_language_from_url_param_quote =
1913 lit_bool_expr_or_idents(&initial_language_from_url_param);
1914 let initial_language_from_url_param_to_local_storage =
1915 lit_bool_expr_or_idents(
1916 &initial_language_from_url_param_to_local_storage,
1917 );
1918 let initial_language_from_url_param_to_session_storage =
1919 lit_bool_expr_or_idents(
1920 &initial_language_from_url_param_to_session_storage,
1921 );
1922 let initial_language_from_url_param_to_cookie_quote =
1923 lit_bool_expr_or_idents(&initial_language_from_url_param_to_cookie);
1924 let initial_language_from_url_param_to_server_function_quote =
1925 lit_bool_expr_or_idents(
1926 &initial_language_from_url_param_to_server_function,
1927 );
1928 let set_language_to_url_param_quote =
1929 lit_bool_expr_or_idents(&set_language_to_url_param);
1930 let local_storage_key_quote = litstr_or_default(
1931 &local_storage_key.lit,
1932 &local_storage_key.expr,
1933 "lang",
1934 );
1935 let initial_language_from_local_storage_quote =
1936 lit_bool_expr_or_idents(&initial_language_from_local_storage);
1937 let initial_language_from_local_storage_to_cookie_quote =
1938 lit_bool_expr_or_idents(
1939 &initial_language_from_local_storage_to_cookie,
1940 );
1941 let initial_language_from_local_storage_to_session_storage_quote =
1942 lit_bool_expr_or_idents(
1943 &initial_language_from_local_storage_to_session_storage,
1944 );
1945 let initial_language_from_local_storage_to_server_function_quote =
1946 lit_bool_expr_or_idents(
1947 &initial_language_from_local_storage_to_server_function,
1948 );
1949 let set_language_to_local_storage_quote =
1950 lit_bool_expr_or_idents(&set_language_to_local_storage);
1951 let session_storage_key_quote = litstr_or_default(
1952 &session_storage_key.lit,
1953 &session_storage_key.expr,
1954 "lang",
1955 );
1956 let initial_language_from_session_storage_quote =
1957 lit_bool_expr_or_idents(&initial_language_from_session_storage);
1958 let initial_language_from_session_storage_to_cookie_quote =
1959 lit_bool_expr_or_idents(
1960 &initial_language_from_session_storage_to_cookie,
1961 );
1962 let initial_language_from_session_storage_to_local_storage_quote =
1963 lit_bool_expr_or_idents(
1964 &initial_language_from_session_storage_to_local_storage,
1965 );
1966 let initial_language_from_session_storage_to_server_function_quote =
1967 lit_bool_expr_or_idents(
1968 &initial_language_from_session_storage_to_server_function,
1969 );
1970 let set_language_to_session_storage_quote =
1971 lit_bool_expr_or_idents(&set_language_to_session_storage);
1972 let initial_language_from_navigator_quote =
1973 lit_bool_expr_or_idents(&initial_language_from_navigator);
1974 let initial_language_from_navigator_to_local_storage_quote =
1975 lit_bool_expr_or_idents(
1976 &initial_language_from_navigator_to_local_storage,
1977 );
1978 let initial_language_from_navigator_to_session_storage_quote =
1979 lit_bool_expr_or_idents(
1980 &initial_language_from_navigator_to_session_storage,
1981 );
1982 let initial_language_from_navigator_to_cookie_quote =
1983 lit_bool_expr_or_idents(&initial_language_from_navigator_to_cookie);
1984 let initial_language_from_navigator_to_server_function_quote =
1985 lit_bool_expr_or_idents(
1986 &initial_language_from_navigator_to_server_function,
1987 );
1988 let set_language_from_navigator_quote =
1989 lit_bool_expr_or_idents(&set_language_from_navigator);
1990 let initial_language_from_accept_language_header_quote =
1991 lit_bool_expr_or_idents(
1992 &initial_language_from_accept_language_header,
1993 );
1994 let cookie_name_quote = litstr_or_default(
1995 &cookie_name.lit,
1996 &cookie_name.expr,
1997 "lf-lang",
1998 );
1999 let cookie_attrs_quote =
2000 litstr_or_default(&cookie_attrs.lit, &cookie_attrs.expr, "");
2001 let initial_language_from_cookie_quote =
2002 lit_bool_expr_or_idents(&initial_language_from_cookie);
2003 let initial_language_from_cookie_to_local_storage_quote =
2004 lit_bool_expr_or_idents(
2005 &initial_language_from_cookie_to_local_storage,
2006 );
2007 let initial_language_from_cookie_to_session_storage_quote =
2008 lit_bool_expr_or_idents(
2009 &initial_language_from_cookie_to_session_storage,
2010 );
2011 let initial_language_from_cookie_to_server_function_quote =
2012 lit_bool_expr_or_idents(
2013 &initial_language_from_cookie_to_server_function,
2014 );
2015 let set_language_to_cookie_quote =
2016 lit_bool_expr_or_idents(&set_language_to_cookie);
2017 let initial_language_from_server_function_quote =
2018 lit_bool_expr_or_idents(
2019 &initial_language_from_server_function,
2020 );
2021 let initial_language_from_server_function_to_cookie_quote =
2022 lit_bool_expr_or_idents(
2023 &initial_language_from_server_function_to_cookie,
2024 );
2025 let initial_language_from_server_function_to_local_storage_quote =
2026 lit_bool_expr_or_idents(
2027 &initial_language_from_server_function_to_local_storage,
2028 );
2029 let set_language_to_server_function_quote =
2030 lit_bool_expr_or_idents(&set_language_to_server_function);
2031 let url_path_quote = if url_path.is_some() {quote!{true}} else {quote!{false}};
2032 let initial_language_from_url_path_quote =
2033 lit_bool_expr_or_idents(&initial_language_from_url_path);
2034 let initial_language_from_url_path_to_cookie_quote =
2035 lit_bool_expr_or_idents(&initial_language_from_url_path_to_cookie);
2036 let initial_language_from_url_path_to_local_storage_quote =
2037 lit_bool_expr_or_idents(
2038 &initial_language_from_url_path_to_local_storage,
2039 );
2040 let initial_language_from_url_path_to_session_storage_quote =
2041 lit_bool_expr_or_idents(
2042 &initial_language_from_url_path_to_session_storage,
2043 );
2044 let initial_language_from_url_path_to_server_function_quote =
2045 lit_bool_expr_or_idents(
2046 &initial_language_from_url_path_to_server_function,
2047 );
2048
2049 let system_quote = {
2050 #[cfg(not(feature = "system"))]
2051 quote! {}
2052
2053 #[cfg(feature = "system")]
2054 {
2055 let initial_language_from_system_quote =
2056 lit_bool_expr_or_idents(&initial_language_from_system);
2057 let initial_language_from_data_file_quote =
2058 lit_bool_expr_or_idents(&initial_language_from_data_file);
2059 let initial_language_from_system_to_data_file_quote =
2060 lit_bool_expr_or_idents(
2061 &initial_language_from_system_to_data_file,
2062 );
2063 let set_language_to_data_file_quote =
2064 lit_bool_expr_or_idents(&set_language_to_data_file);
2065 let data_file_key_quote = litstr_or_default(
2066 &data_file_key.lit,
2067 &data_file_key.expr,
2068 "leptos-fluent",
2069 );
2070
2071 quote! {
2072 initial_language_from_system: #initial_language_from_system_quote,
2073 initial_language_from_data_file: #initial_language_from_data_file_quote,
2074 initial_language_from_system_to_data_file: #initial_language_from_system_to_data_file_quote,
2075 set_language_to_data_file: #set_language_to_data_file_quote,
2076 data_file_key: #data_file_key_quote,
2077 }
2078 }
2079 };
2080
2081 let quote = quote! {
2082 const meta: ::leptos_fluent::LeptosFluentMeta = ::leptos_fluent::LeptosFluentMeta {
2083 locales: #locales_path,
2084 core_locales: #core_locales_quote,
2085 languages: #languages_quote,
2086 default_language: #default_language_quote,
2087 translations: #translations_quote,
2088 check_translations: #check_translations_quote,
2089 fill_translations: #fill_translations_quote,
2090 sync_html_tag_lang: #sync_html_tag_lang_quote,
2091 sync_html_tag_dir: #sync_html_tag_dir_quote,
2092 url_param: #url_param_quote,
2093 initial_language_from_url_param: #initial_language_from_url_param_quote,
2094 initial_language_from_url_param_to_local_storage: #initial_language_from_url_param_to_local_storage,
2095 initial_language_from_url_param_to_session_storage: #initial_language_from_url_param_to_session_storage,
2096 initial_language_from_url_param_to_cookie: #initial_language_from_url_param_to_cookie_quote,
2097 initial_language_from_url_param_to_server_function: #initial_language_from_url_param_to_server_function_quote,
2098 set_language_to_url_param: #set_language_to_url_param_quote,
2099 local_storage_key: #local_storage_key_quote,
2100 initial_language_from_local_storage: #initial_language_from_local_storage_quote,
2101 initial_language_from_local_storage_to_cookie: #initial_language_from_local_storage_to_cookie_quote,
2102 initial_language_from_local_storage_to_session_storage: #initial_language_from_local_storage_to_session_storage_quote,
2103 initial_language_from_local_storage_to_server_function: #initial_language_from_local_storage_to_server_function_quote,
2104 set_language_to_local_storage: #set_language_to_local_storage_quote,
2105 session_storage_key: #session_storage_key_quote,
2106 initial_language_from_session_storage: #initial_language_from_session_storage_quote,
2107 initial_language_from_session_storage_to_cookie: #initial_language_from_session_storage_to_cookie_quote,
2108 initial_language_from_session_storage_to_local_storage: #initial_language_from_session_storage_to_local_storage_quote,
2109 initial_language_from_session_storage_to_server_function: #initial_language_from_session_storage_to_server_function_quote,
2110 set_language_to_session_storage: #set_language_to_session_storage_quote,
2111 initial_language_from_navigator: #initial_language_from_navigator_quote,
2112 initial_language_from_navigator_to_local_storage: #initial_language_from_navigator_to_local_storage_quote,
2113 initial_language_from_navigator_to_session_storage: #initial_language_from_navigator_to_session_storage_quote,
2114 initial_language_from_navigator_to_cookie: #initial_language_from_navigator_to_cookie_quote,
2115 initial_language_from_navigator_to_server_function: #initial_language_from_navigator_to_server_function_quote,
2116 set_language_from_navigator: #set_language_from_navigator_quote,
2117 initial_language_from_accept_language_header: #initial_language_from_accept_language_header_quote,
2118 cookie_name: #cookie_name_quote,
2119 cookie_attrs: #cookie_attrs_quote,
2120 initial_language_from_cookie: #initial_language_from_cookie_quote,
2121 initial_language_from_cookie_to_local_storage: #initial_language_from_cookie_to_local_storage_quote,
2122 initial_language_from_cookie_to_session_storage: #initial_language_from_cookie_to_session_storage_quote,
2123 initial_language_from_cookie_to_server_function: #initial_language_from_cookie_to_server_function_quote,
2124 set_language_to_cookie: #set_language_to_cookie_quote,
2125 initial_language_from_server_function: #initial_language_from_server_function_quote,
2126 initial_language_from_server_function_to_cookie: #initial_language_from_server_function_to_cookie_quote,
2127 initial_language_from_server_function_to_local_storage: #initial_language_from_server_function_to_local_storage_quote,
2128 set_language_to_server_function: #set_language_to_server_function_quote,
2129 url_path: #url_path_quote,
2130 initial_language_from_url_path: #initial_language_from_url_path_quote,
2131 initial_language_from_url_path_to_cookie: #initial_language_from_url_path_to_cookie_quote,
2132 initial_language_from_url_path_to_local_storage: #initial_language_from_url_path_to_local_storage_quote,
2133 initial_language_from_url_path_to_session_storage: #initial_language_from_url_path_to_session_storage_quote,
2134 initial_language_from_url_path_to_server_function: #initial_language_from_url_path_to_server_function_quote,
2135 provide_meta_context: true,
2136 #system_quote
2137 };
2138 ::leptos::context::provide_context::<::leptos_fluent::LeptosFluentMeta>(meta);
2139 };
2140
2141 match param.exprpath {
2142 Some(ref path) => quote! { #path{#quote}; },
2143 None => quote,
2144 }
2145 }
2146 false => quote!(),
2147 }
2148 }).collect()
2149 };
2150
2151 let warnings_quote: proc_macro2::TokenStream =
2152 warnings.iter().map(|warning| quote!(#warning)).collect();
2153 let other_quotes = quote! {
2154 #sync_language_with_server_function_quote
2155 #sync_language_with_local_storage_quote
2156 #sync_language_with_session_storage_quote
2157 #sync_language_with_url_param_quote
2158 #sync_language_with_cookie_quote
2159 #sync_language_with_data_file_quote
2160 #set_language_from_navigator_quote
2161 #files_tracker_quote
2162 #leptos_fluent_provide_meta_context_quote
2163 #warnings_quote
2164 };
2165
2166 let initial_language_index = match default_language {
2167 Some((_, index)) => index,
2168 None => 0,
2169 };
2170
2171 let (fluent_templates_quote, translations_quote) = match translations {
2172 Some(ref translations) => (quote!(), quote!(#translations)),
2173 None => {
2174 let fallback_language =
2175 &languages[initial_language_index].0.to_string();
2176
2177 let core_locales_quote = match &core_locales_path {
2178 Some(ref path) => quote!(core_locales: #path,),
2179 None => quote!(),
2180 };
2181
2182 let (customise_quote, warnings_quote) = {
2183 #[cfg(feature = "disable-unicode-isolating-marks")]
2184 {
2185 (
2186 customise.map_or(
2187 quote!(customise: |bundle| bundle.set_use_isolating(false),),
2188 |c| quote! {
2189 customise: |bundle| {
2190 bundle.set_use_isolating(false);
2191 let customise: fn(&mut ::leptos_fluent::__reexports::fluent_templates::FluentBundle<&::leptos_fluent::__reexports::fluent_bundle::FluentResource>) = #c;
2192 customise(bundle);
2193 },
2194 }
2195 ),
2196 {
2197 let warning = proc_macro_warning::FormattedWarning::new_deprecated(
2200 "disable_unicode_isolating_marks",
2201 "The feature `disable-unicode-isolating-marks` has been deprecated \
2202 and will be removed in v0.3.0. Use the `customise` argument of \
2203 `leptos_fluent!` macro with the value \
2204 `|bundle| bundle.set_use_isolating(false)` instead to disable Unicode \
2205 isolating marks in translations.",
2206 proc_macro2::Span::call_site(),
2207 );
2208 quote!(#warning)
2209 },
2210 )
2211 }
2212
2213 #[cfg(not(feature = "disable-unicode-isolating-marks"))]
2214 {
2215 (
2216 customise
2217 .map_or(quote!(), |c| quote! { customise: #c, }),
2218 quote!(),
2219 )
2220 }
2221 };
2222
2223 (
2224 quote! {
2225 use ::leptos_fluent::__reexports::fluent_templates::{static_loader, self};
2226 static_loader! {
2227 static TRS = {
2228 locales: #locales_path,
2229 fallback_language: #fallback_language,
2230 #core_locales_quote
2231 #customise_quote
2232 };
2233 }
2234 #warnings_quote
2235 },
2236 quote!(vec![&TRS]),
2237 )
2238 }
2239 };
2240
2241 let init_quote = quote! {
2242 {
2243 let mut lang: Option<&'static ::leptos_fluent::Language> = None;
2244 #initial_language_quote;
2245
2246 let initial_lang = if let Some(l) = lang {
2247 l
2248 } else {
2249 LANGUAGES[#initial_language_index]
2250 };
2251
2252 #fluent_templates_quote;
2253
2254 let i18n = ::leptos_fluent::I18n {
2255 language: ::leptos::prelude::RwSignal::new(initial_lang),
2256 languages: &LANGUAGES,
2257 translations: ::leptos::prelude::Signal::derive(move || #translations_quote),
2258 };
2259 ::leptos::context::provide_context::<::leptos_fluent::I18n>(i18n);
2260 i18n
2261 }
2262 };
2263
2264 let children_quote: proc_macro2::TokenStream = children
2265 .iter()
2266 .map(|param| {
2267 let expr = param.expr.as_ref().unwrap();
2268 match param.exprpath {
2269 Some(ref path) => quote!(#path{#expr}),
2270 None => quote!(#expr),
2271 }
2272 })
2273 .collect();
2274
2275 let quote = quote! {
2276 let i18n = {
2277 const LANGUAGES: [&::leptos_fluent::Language; #n_languages] =
2278 #languages_quote;
2279 let i18n = #init_quote;
2280 #other_quotes
2281 i18n
2282 };
2283 {
2284 use ::leptos::context::Provider;
2285 ::leptos::prelude::view! {
2286 <Provider value={i18n}>
2287 #sync_html_tag_quote
2288 {#children_quote}
2289 </Provider>
2290 }
2291 }
2292 };
2293
2294 #[cfg(feature = "debug")]
2295 debug(&format!("\n{}", "e.to_string()));
2296
2297 #[cfg(feature = "tracing")]
2298 tracing::trace!("{}", "e.to_string());
2299
2300 proc_macro::TokenStream::from(quote)
2301}
2302
2303#[cfg(test)]
2304mod tests {
2305 use trybuild;
2306
2307 #[test]
2308 fn leptos_fluent_trybuild_pass() {
2309 let t = trybuild::TestCases::new();
2310
2311 #[cfg(feature = "nightly")]
2312 t.pass("tests/ui/leptos_fluent/nightly/pass/*.rs");
2313
2314 #[cfg(not(feature = "nightly"))]
2316 {
2317 t.pass("tests/ui/leptos_fluent/nightly/pass/*.rs");
2318 t.pass("tests/ui/leptos_fluent/stable/pass/*.rs");
2319 }
2320 }
2321
2322 #[cfg(not(feature = "nightly"))]
2323 #[test]
2324 fn leptos_fluent_trybuild_fail() {
2325 let t = trybuild::TestCases::new();
2326 t.compile_fail("tests/ui/leptos_fluent/stable/fail/*.rs");
2327 }
2328}