use crate::Loader;
use fluent_bundle::FluentValue;
use std::borrow::Cow;
use std::collections::{HashMap, VecDeque};
pub use unic_langid::LanguageIdentifier;
pub struct MultiLoader<T = Box<dyn Loader + Sync + Send>> {
loaders: VecDeque<T>,
}
impl<T> MultiLoader<T> {
pub fn new() -> Self {
Self::default()
}
pub fn from_iter(iter: impl IntoIterator<Item = T>) -> Self {
Self {
loaders: iter.into_iter().collect(),
}
}
pub fn push_front(&mut self, loader: T) {
self.loaders.push_front(loader);
}
pub fn push_back(&mut self, loader: T) {
self.loaders.push_back(loader);
}
pub fn remove(&mut self, idx: usize) -> Option<T> {
self.loaders.remove(idx)
}
}
impl<T> Default for MultiLoader<T> {
fn default() -> Self {
Self {
loaders: VecDeque::default(),
}
}
}
impl<T: Loader> crate::Loader for MultiLoader<T> {
fn lookup_complete(
&self,
lang: &unic_langid::LanguageIdentifier,
text_id: &str,
args: Option<&std::collections::HashMap<Cow<'static, str>, fluent_bundle::FluentValue>>,
) -> String {
for loader in self.loaders.iter() {
if let Some(text) = loader.try_lookup_complete(lang, text_id, args) {
return text;
}
}
format!("Unknown localization key: {text_id:?}")
}
fn try_lookup_complete(
&self,
lang: &LanguageIdentifier,
text_id: &str,
args: Option<&HashMap<Cow<'static, str>, FluentValue>>,
) -> Option<String> {
for loader in self.loaders.iter() {
if let Some(text) = loader.try_lookup_complete(lang, text_id, args) {
return Some(text);
}
}
None
}
fn locales(&self) -> Box<dyn Iterator<Item = &LanguageIdentifier> + '_> {
Box::new(self.loaders.iter().flat_map(|loader| loader.locales()))
}
}