use crate::cache::{ChangeSet, ICacheUpdater, IGroup, IObservableCache, ObservableCache};
use ferroui_system::IDisposable;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::rc::Rc;
struct Inner<T, K, G> {
key: G,
cache: ObservableCache<T, K>,
}
pub struct Group<T, K, G> {
inner: Rc<Inner<T, K, G>>,
}
impl<T, K, G> Clone for Group<T, K, G> {
fn clone(&self) -> Self {
Self { inner: self.inner.clone() }
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static, G> Group<T, K, G> {
pub(crate) fn new(key: G) -> Self {
Self { inner: Rc::new(Inner { key, cache: ObservableCache::without_key_selector() }) }
}
pub fn key(&self) -> &G {
&self.inner.key
}
pub fn cache(&self) -> Rc<dyn IObservableCache<T, K>> {
Rc::new(self.inner.cache.clone())
}
pub(crate) fn observable_cache(&self) -> &ObservableCache<T, K> {
&self.inner.cache
}
pub(crate) fn count(&self) -> usize {
self.inner.cache.count()
}
pub(crate) fn suspend_notifications(&self) -> Rc<dyn IDisposable> {
self.inner.cache.suspend_notifications()
}
pub(crate) fn get_initial_updates(&self) -> ChangeSet<T, K> {
self.inner.cache.get_initial_updates(None)
}
pub(crate) fn update(&self, update_action: impl FnOnce(&mut dyn ICacheUpdater<T, K>)) {
self.inner.cache.update_from_intermediate(update_action);
}
pub fn ptr_eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.inner, &other.inner)
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static, G> IGroup<T, K, G> for Group<T, K, G> {
fn key(&self) -> &G {
&self.inner.key
}
fn cache(&self) -> Rc<dyn IObservableCache<T, K>> {
Rc::new(self.inner.cache.clone())
}
}
impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static, G> IDisposable for Group<T, K, G> {
fn dispose(&self) {
self.inner.cache.dispose();
}
}
impl<T, K, G: PartialEq> PartialEq for Group<T, K, G> {
fn eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.inner, &other.inner) || self.inner.key == other.inner.key
}
}
impl<T, K, G: Eq> Eq for Group<T, K, G> {}
impl<T, K, G: Hash> Hash for Group<T, K, G> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner.key.hash(state);
}
}
impl<T, K, G: fmt::Display> fmt::Display for Group<T, K, G> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Group: {}", self.inner.key)
}
}
impl<T, K, G: fmt::Debug> fmt::Debug for Group<T, K, G> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Group: {:?}", self.inner.key)
}
}