1#![doc = include_str!("../README.md")]
2
3#[doc(hidden)]
4pub mod meta;
5
6#[doc(hidden)]
7pub mod registry;
8
9#[cfg(feature = "derive")]
10pub use es_fluent_derive::{EsFluent, EsFluentChoice, EsFluentThis, EsFluentVariants};
11
12#[doc(hidden)]
13pub use fluent_bundle::FluentValue;
14
15#[doc(hidden)]
16pub use inventory as __inventory;
17
18#[doc(hidden)]
19pub use rust_embed as __rust_embed;
20
21#[doc(hidden)]
22pub use es_fluent_manager_core as __manager_core;
23
24#[doc(hidden)]
25pub use unic_langid;
26
27use arc_swap::ArcSwap;
28use es_fluent_manager_core::FluentManager;
29use std::sync::{Arc, OnceLock};
30
31mod traits;
32pub use traits::{EsFluentChoice, FluentDisplay, ThisFtl, ToFluentString};
33
34#[doc(hidden)]
35static CONTEXT: OnceLock<ArcSwap<FluentManager>> = OnceLock::new();
36
37#[doc(hidden)]
38static CUSTOM_LOCALIZER: OnceLock<
39 Box<
40 dyn Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
41 + Send
42 + Sync,
43 >,
44> = OnceLock::new();
45
46#[doc(hidden)]
55pub fn set_context(manager: FluentManager) {
56 CONTEXT
57 .set(ArcSwap::from_pointee(manager))
58 .map_err(|_| "Context already set")
59 .expect("Failed to set context");
60}
61
62#[doc(hidden)]
71pub fn set_shared_context(manager: Arc<FluentManager>) {
72 CONTEXT
73 .set(ArcSwap::new(manager))
74 .map_err(|_| "Context already set")
75 .expect("Failed to set shared context");
76}
77
78#[doc(hidden)]
88pub fn set_custom_localizer<F>(localizer: F)
89where
90 F: Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
91 + Send
92 + Sync
93 + 'static,
94{
95 CUSTOM_LOCALIZER
96 .set(Box::new(localizer))
97 .map_err(|_| "Custom localizer already set")
98 .expect("Failed to set custom localizer");
99}
100
101#[doc(hidden)]
103pub fn select_language(lang: &unic_langid::LanguageIdentifier) {
104 if let Some(context) = CONTEXT.get() {
105 context.load().select_language(lang);
106 }
107}
108
109#[doc(hidden)]
118pub fn localize<'a>(
119 id: &str,
120 args: Option<&std::collections::HashMap<&str, FluentValue<'a>>>,
121) -> String {
122 if let Some(custom_localizer) = CUSTOM_LOCALIZER.get()
123 && let Some(message) = custom_localizer(id, args)
124 {
125 return message;
126 }
127
128 if let Some(context) = CONTEXT.get()
129 && let Some(message) = context.load().localize(id, args)
130 {
131 return message;
132 }
133
134 tracing::warn!("Translation for '{}' not found or context not set.", id);
135 id.to_string()
136}