use crate::{ bundles::Bundles, env::LocalesProvider, generator::{BundleGenerator, BundleIterator, BundleStream}, types::ResourceId, }; use once_cell::sync::OnceCell; use rustc_hash::FxHashSet; use std::rc::Rc; pub struct Localization where G: BundleGenerator, P: LocalesProvider, { bundles: OnceCell>>, generator: G, provider: P, sync: bool, res_ids: FxHashSet, } impl Localization where G: BundleGenerator + Default, P: LocalesProvider + Default, { pub fn new(res_ids: I, sync: bool) -> Self where I: IntoIterator, { Self { bundles: OnceCell::new(), generator: G::default(), provider: P::default(), sync, res_ids: FxHashSet::from_iter(res_ids.into_iter()), } } } impl Localization where G: BundleGenerator, P: LocalesProvider, { pub fn with_env(res_ids: I, sync: bool, provider: P, generator: G) -> Self where I: IntoIterator, { Self { bundles: OnceCell::new(), generator, provider, sync, res_ids: FxHashSet::from_iter(res_ids.into_iter()), } } pub fn is_sync(&self) -> bool { self.sync } pub fn add_resource_id>(&mut self, res_id: T) { self.res_ids.insert(res_id.into()); self.on_change(); } pub fn add_resource_ids(&mut self, res_ids: Vec) { self.res_ids.extend(res_ids); self.on_change(); } pub fn remove_resource_id>(&mut self, res_id: T) -> usize { self.res_ids.retain(|x| !res_id.eq(x)); self.on_change(); self.res_ids.len() } pub fn remove_resource_ids(&mut self, res_ids: Vec) -> usize { self.res_ids.retain(|x| !res_ids.contains(x)); self.on_change(); self.res_ids.len() } pub fn set_async(&mut self) { if self.sync { self.sync = false; self.on_change(); } } pub fn on_change(&mut self) { self.bundles.take(); } } impl Localization where G: BundleGenerator, G::Iter: BundleIterator, P: LocalesProvider, { pub fn prefetch_sync(&mut self) { let bundles = self.bundles(); bundles.prefetch_sync(); } } impl Localization where G: BundleGenerator, G::Stream: BundleStream, P: LocalesProvider, { pub async fn prefetch_async(&mut self) { let bundles = self.bundles(); bundles.prefetch_async().await } } impl Localization where G: BundleGenerator, P: LocalesProvider, { pub fn bundles(&self) -> &Rc> { self.bundles.get_or_init(|| { Rc::new(Bundles::new( self.sync, self.res_ids.clone(), &self.generator, &self.provider, )) }) } }