use super::internal::KeySelector;
use super::{Change, ChangeSet, IConnectableCache, IObservableCache, ISourceUpdater, ObservableCache};
use ferroui_system::collections::generic::Dictionary;
use ferroui_system::{IDisposable, IObservable};
use std::hash::Hash;
use std::rc::Rc;
pub trait ISourceCache<T, K>: IObservableCache<T, K> {
fn key_selector(&self) -> KeySelector<T, K>;
fn edit(&self, update: &mut dyn FnMut(&mut dyn ISourceUpdater<T, K>));
}
pub struct SourceCache<T, K> {
inner: ObservableCache<T, K>,
key_selector: KeySelector<T, K>,
}
impl<T, K> Clone for SourceCache<T, K> {
fn clone(&self) -> Self {
Self { inner: self.inner.clone(), key_selector: self.key_selector.clone() }
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> SourceCache<T, K> {
pub fn new(key_selector: impl Fn(&T) -> K + 'static) -> Self {
let key_selector: KeySelector<T, K> = Rc::new(key_selector);
let selector = key_selector.clone();
Self { inner: ObservableCache::new(move |item| selector(item)), key_selector }
}
pub fn edit(&self, update: impl FnOnce(&mut dyn ISourceUpdater<T, K>)) {
self.inner.update_from_source(update);
}
pub fn suspend_count(&self) -> Rc<dyn IDisposable> {
self.inner.suspend_count()
}
pub fn suspend_notifications(&self) -> Rc<dyn IDisposable> {
self.inner.suspend_notifications()
}
pub fn as_observable_cache_inner(&self) -> &ObservableCache<T, K> {
&self.inner
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IConnectableCache<T, K> for SourceCache<T, K> {
fn count_changed(&self) -> Rc<dyn IObservable<usize>> {
self.inner.count_changed()
}
fn connect_with(&self, predicate: Option<Rc<dyn Fn(&T) -> bool>>, suppress_empty_change_sets: bool) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
self.inner.connect_with(predicate, suppress_empty_change_sets)
}
fn preview_with(&self, predicate: Option<Rc<dyn Fn(&T) -> bool>>) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
self.inner.preview_with(predicate)
}
fn watch(&self, key: K) -> Rc<dyn IObservable<Change<T, K>>> {
self.inner.watch(key)
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IObservableCache<T, K> for SourceCache<T, K> {
fn count(&self) -> usize {
self.inner.count()
}
fn items(&self) -> Vec<T> {
self.inner.items()
}
fn keys(&self) -> Vec<K> {
self.inner.keys()
}
fn key_values(&self) -> Dictionary<K, T> {
self.inner.key_values()
}
fn lookup(&self, key: &K) -> Option<T> {
self.inner.lookup(key)
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> ISourceCache<T, K> for SourceCache<T, K> {
fn key_selector(&self) -> KeySelector<T, K> {
self.key_selector.clone()
}
fn edit(&self, update: &mut dyn FnMut(&mut dyn ISourceUpdater<T, K>)) {
self.inner.update_from_source(|updater| update(updater));
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IDisposable for SourceCache<T, K> {
fn dispose(&self) {
self.inner.dispose();
}
}