1#![doc = include_str!("../README.md")]
2
3#[cfg(feature = "derive")]
4pub use es_fluent_derive::{EsFluent, EsFluentChoice, EsFluentKv, EsFluentThis};
5
6#[doc(hidden)]
7pub use es_fluent_manager_core::{FluentManager, I18nModule, LocalizationError, Localizer};
8
9#[doc(hidden)]
10pub use fluent_bundle::FluentValue;
11
12#[doc(hidden)]
13pub use inventory as __inventory;
14
15#[doc(hidden)]
16pub use rust_embed as __rust_embed;
17
18#[doc(hidden)]
19pub use es_fluent_manager_core as __manager_core;
20
21#[doc(hidden)]
22pub use es_fluent_core as __core;
23
24#[doc(hidden)]
25pub use unic_langid;
26
27mod traits;
28pub use traits::{EsFluentChoice, FluentDisplay, ThisFtl, ToFluentString};
29
30use std::sync::{Arc, OnceLock, RwLock};
31
32#[doc(hidden)]
33static CONTEXT: OnceLock<Arc<RwLock<FluentManager>>> = OnceLock::new();
34
35#[doc(hidden)]
36static CUSTOM_LOCALIZER: OnceLock<
37 Box<
38 dyn Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
39 + Send
40 + Sync,
41 >,
42> = OnceLock::new();
43
44#[doc(hidden)]
53pub fn set_context(manager: FluentManager) {
54 CONTEXT
55 .set(Arc::new(RwLock::new(manager)))
56 .map_err(|_| "Context already set")
57 .expect("Failed to set context");
58}
59
60#[doc(hidden)]
69pub fn set_shared_context(manager: Arc<RwLock<FluentManager>>) {
70 CONTEXT
71 .set(manager)
72 .map_err(|_| "Context already set")
73 .expect("Failed to set shared context");
74}
75
76#[doc(hidden)]
86pub fn set_custom_localizer<F>(localizer: F)
87where
88 F: Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
89 + Send
90 + Sync
91 + 'static,
92{
93 CUSTOM_LOCALIZER
94 .set(Box::new(localizer))
95 .map_err(|_| "Custom localizer already set")
96 .expect("Failed to set custom localizer");
97}
98
99#[doc(hidden)]
101pub fn update_context<F>(f: F)
102where
103 F: FnOnce(&mut FluentManager),
104{
105 if let Some(context_arc) = CONTEXT.get() {
106 let mut context = context_arc
107 .write()
108 .expect("Failed to acquire write lock on context");
109 f(&mut context);
110 }
111}
112
113#[doc(hidden)]
122pub fn localize<'a>(
123 id: &str,
124 args: Option<&std::collections::HashMap<&str, FluentValue<'a>>>,
125) -> String {
126 if let Some(custom_localizer) = CUSTOM_LOCALIZER.get()
127 && let Some(message) = custom_localizer(id, args)
128 {
129 return message;
130 }
131
132 if let Some(context_arc) = CONTEXT.get() {
133 let context = context_arc
134 .read()
135 .expect("Failed to acquire read lock on context");
136
137 if let Some(message) = context.localize(id, args) {
138 return message;
139 }
140 }
141
142 tracing::warn!("Translation for '{}' not found or context not set.", id);
143 id.to_string()
144}