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
31#[cfg(feature = "build")]
32pub mod build {
33 pub use es_fluent_toml::build::*;
34}
35
36mod traits;
37pub use traits::{EsFluentChoice, FluentDisplay, ThisFtl, ToFluentString};
38
39#[doc(hidden)]
40static CONTEXT: OnceLock<ArcSwap<FluentManager>> = OnceLock::new();
41
42#[doc(hidden)]
43static CUSTOM_LOCALIZER: OnceLock<
44 Box<
45 dyn Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
46 + Send
47 + Sync,
48 >,
49> = OnceLock::new();
50
51#[doc(hidden)]
60pub fn set_context(manager: FluentManager) {
61 CONTEXT
62 .set(ArcSwap::from_pointee(manager))
63 .map_err(|_| "Context already set")
64 .expect("Failed to set context");
65}
66
67#[doc(hidden)]
76pub fn set_shared_context(manager: Arc<FluentManager>) {
77 CONTEXT
78 .set(ArcSwap::new(manager))
79 .map_err(|_| "Context already set")
80 .expect("Failed to set shared context");
81}
82
83#[doc(hidden)]
93pub fn set_custom_localizer<F>(localizer: F)
94where
95 F: Fn(&str, Option<&std::collections::HashMap<&str, FluentValue>>) -> Option<String>
96 + Send
97 + Sync
98 + 'static,
99{
100 CUSTOM_LOCALIZER
101 .set(Box::new(localizer))
102 .map_err(|_| "Custom localizer already set")
103 .expect("Failed to set custom localizer");
104}
105
106#[doc(hidden)]
108pub fn select_language(lang: &unic_langid::LanguageIdentifier) {
109 if let Some(context) = CONTEXT.get() {
110 context.load().select_language(lang);
111 }
112}
113
114#[doc(hidden)]
123pub fn localize<'a>(
124 id: &str,
125 args: Option<&std::collections::HashMap<&str, FluentValue<'a>>>,
126) -> String {
127 if let Some(custom_localizer) = CUSTOM_LOCALIZER.get()
128 && let Some(message) = custom_localizer(id, args)
129 {
130 return message;
131 }
132
133 if let Some(context) = CONTEXT.get()
134 && let Some(message) = context.load().localize(id, args)
135 {
136 return message;
137 }
138
139 tracing::warn!("Translation for '{}' not found or context not set.", id);
140 id.to_string()
141}