1#![doc = include_str!("../README.md")]
2
3#[cfg(feature = "derive")]
4pub use es_fluent_derive::{EsFluent, EsFluentChoice, EsFluentKv};
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 unic_langid;
23
24mod traits;
25pub use traits::{EsFluentChoice, FluentDisplay, ToFluentString};
26
27use std::sync::{Arc, OnceLock, RwLock};
28
29#[doc(hidden)]
30static CONTEXT: OnceLock<Arc<RwLock<FluentManager>>> = OnceLock::new();
31
32#[doc(hidden)]
33static CUSTOM_LOCALIZER: OnceLock<
34 Box<
35 dyn Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
36 + Send
37 + Sync,
38 >,
39> = OnceLock::new();
40
41#[doc(hidden)]
50pub fn set_context(manager: FluentManager) {
51 CONTEXT
52 .set(Arc::new(RwLock::new(manager)))
53 .map_err(|_| "Context already set")
54 .expect("Failed to set context");
55}
56
57#[doc(hidden)]
66pub fn set_shared_context(manager: Arc<RwLock<FluentManager>>) {
67 CONTEXT
68 .set(manager)
69 .map_err(|_| "Context already set")
70 .expect("Failed to set shared context");
71}
72
73#[doc(hidden)]
83pub fn set_custom_localizer<F>(localizer: F)
84where
85 F: Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
86 + Send
87 + Sync
88 + 'static,
89{
90 CUSTOM_LOCALIZER
91 .set(Box::new(localizer))
92 .map_err(|_| "Custom localizer already set")
93 .expect("Failed to set custom localizer");
94}
95
96#[doc(hidden)]
98pub fn update_context<F>(f: F)
99where
100 F: FnOnce(&mut FluentManager),
101{
102 if let Some(context_arc) = CONTEXT.get() {
103 let mut context = context_arc
104 .write()
105 .expect("Failed to acquire write lock on context");
106 f(&mut context);
107 }
108}
109
110#[doc(hidden)]
119pub fn localize<'a>(
120 id: &str,
121 args: Option<&std::collections::HashMap<&str, FluentValue<'a>>>,
122) -> String {
123 if let Some(custom_localizer) = CUSTOM_LOCALIZER.get()
124 && let Some(message) = custom_localizer(id, args)
125 {
126 return message;
127 }
128
129 if let Some(context_arc) = CONTEXT.get() {
130 let context = context_arc
131 .read()
132 .expect("Failed to acquire read lock on context");
133
134 if let Some(message) = context.localize(id, args) {
135 return message;
136 }
137 }
138
139 log::warn!("Translation for '{}' not found or context not set.", id);
140 id.to_string()
141}