#[cfg(feature = "handlebars")]
mod handlebars;
#[cfg(feature = "tera")]
mod tera;
use std::collections::HashMap;
use fluent_bundle::concurrent::FluentBundle;
use fluent_bundle::{FluentResource, FluentValue};
use fluent_langneg::negotiate_languages;
pub use unic_langid::{langid, langids, LanguageIdentifier};
mod arc_loader;
mod static_loader;
pub use arc_loader::{ArcLoader, ArcLoaderBuilder};
pub use static_loader::StaticLoader;
pub trait Loader {
fn lookup(&self, lang: &LanguageIdentifier, text_id: &str) -> String {
self.lookup_complete(lang, text_id, None)
}
fn lookup_with_args(
&self,
lang: &LanguageIdentifier,
text_id: &str,
args: &HashMap<String, FluentValue>,
) -> String {
self.lookup_complete(lang, text_id, Some(args))
}
fn lookup_complete(
&self,
lang: &LanguageIdentifier,
text_id: &str,
args: Option<&HashMap<String, FluentValue>>,
) -> String;
}
impl<L> Loader for std::sync::Arc<L>
where
L: Loader,
{
fn lookup_complete(
&self,
lang: &LanguageIdentifier,
text_id: &str,
args: Option<&HashMap<String, FluentValue>>,
) -> String {
L::lookup_complete(self, lang, text_id, args)
}
}
impl<'a, L> Loader for &'a L
where
L: Loader,
{
fn lookup_complete(
&self,
lang: &LanguageIdentifier,
text_id: &str,
args: Option<&HashMap<String, FluentValue>>,
) -> String {
L::lookup_complete(self, lang, text_id, args)
}
}
pub struct FluentLoader<L> {
loader: L,
}
impl<L> FluentLoader<L> {
pub fn new(loader: L) -> Self {
Self { loader }
}
}
pub fn build_fallbacks(
locales: &[LanguageIdentifier],
) -> HashMap<LanguageIdentifier, Vec<LanguageIdentifier>> {
let mut map = HashMap::new();
for locale in locales.iter() {
map.insert(
locale.to_owned(),
negotiate_languages(
&[locale],
locales,
None,
fluent_langneg::NegotiationStrategy::Filtering,
)
.into_iter()
.cloned()
.collect::<Vec<_>>(),
);
}
map
}
fn create_bundle(
lang: LanguageIdentifier,
resources: &'static [FluentResource],
core_resource: Option<&'static FluentResource>,
customizer: &impl Fn(&mut FluentBundle<&'static FluentResource>),
) -> FluentBundle<&'static FluentResource> {
let mut bundle: FluentBundle<&'static FluentResource> = FluentBundle::new(&[lang]);
if let Some(core) = core_resource {
bundle
.add_resource(core)
.expect("Failed to add core resource to bundle");
}
for res in resources {
bundle
.add_resource(res)
.expect("Failed to add FTL resources to the bundle.");
}
customizer(&mut bundle);
bundle
}
pub fn build_bundles(
resources: &'static HashMap<LanguageIdentifier, Vec<FluentResource>>,
core_resource: Option<&'static FluentResource>,
customizer: impl Fn(&mut FluentBundle<&'static FluentResource>),
) -> HashMap<LanguageIdentifier, FluentBundle<&'static FluentResource>> {
let mut bundles = HashMap::new();
for (k, ref v) in resources.iter() {
bundles.insert(
k.clone(),
create_bundle(k.clone(), &v, core_resource, &customizer),
);
}
bundles
}
fn map_to_str_map<'a>(
map: Option<&'a HashMap<String, FluentValue>>,
) -> Option<HashMap<&'a str, FluentValue<'a>>> {
let mut new = HashMap::with_capacity(map.map(HashMap::len).unwrap_or(0));
if let Some(map) = map {
for (key, value) in map.iter() {
new.insert(&**key, value.clone());
}
}
Some(new)
}