ferroui_dynamic_data/cache/
source_cache.rs1use super::internal::KeySelector;
5use super::{Change, ChangeSet, IConnectableCache, IObservableCache, ISourceUpdater, ObservableCache};
6use ferroui_system::collections::generic::Dictionary;
7use ferroui_system::{IDisposable, IObservable};
8use std::hash::Hash;
9use std::rc::Rc;
10
11pub trait ISourceCache<T, K>: IObservableCache<T, K> {
13 fn key_selector(&self) -> KeySelector<T, K>;
15 fn edit(&self, update: &mut dyn FnMut(&mut dyn ISourceUpdater<T, K>));
17}
18
19pub struct SourceCache<T, K> {
22 inner: ObservableCache<T, K>,
23 key_selector: KeySelector<T, K>,
24}
25
26impl<T, K> Clone for SourceCache<T, K> {
27 fn clone(&self) -> Self {
28 Self { inner: self.inner.clone(), key_selector: self.key_selector.clone() }
29 }
30}
31
32impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> SourceCache<T, K> {
33 pub fn new(key_selector: impl Fn(&T) -> K + 'static) -> Self {
35 let key_selector: KeySelector<T, K> = Rc::new(key_selector);
36 let selector = key_selector.clone();
37 Self { inner: ObservableCache::new(move |item| selector(item)), key_selector }
38 }
39
40 pub fn edit(&self, update: impl FnOnce(&mut dyn ISourceUpdater<T, K>)) {
42 self.inner.update_from_source(update);
43 }
44
45 pub fn suspend_count(&self) -> Rc<dyn IDisposable> {
47 self.inner.suspend_count()
48 }
49
50 pub fn suspend_notifications(&self) -> Rc<dyn IDisposable> {
52 self.inner.suspend_notifications()
53 }
54
55 pub fn as_observable_cache_inner(&self) -> &ObservableCache<T, K> {
57 &self.inner
58 }
59}
60
61impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IConnectableCache<T, K> for SourceCache<T, K> {
62 fn count_changed(&self) -> Rc<dyn IObservable<usize>> {
63 self.inner.count_changed()
64 }
65
66 fn connect_with(&self, predicate: Option<Rc<dyn Fn(&T) -> bool>>, suppress_empty_change_sets: bool) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
67 self.inner.connect_with(predicate, suppress_empty_change_sets)
68 }
69
70 fn preview_with(&self, predicate: Option<Rc<dyn Fn(&T) -> bool>>) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
71 self.inner.preview_with(predicate)
72 }
73
74 fn watch(&self, key: K) -> Rc<dyn IObservable<Change<T, K>>> {
75 self.inner.watch(key)
76 }
77}
78
79impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IObservableCache<T, K> for SourceCache<T, K> {
80 fn count(&self) -> usize {
81 self.inner.count()
82 }
83
84 fn items(&self) -> Vec<T> {
85 self.inner.items()
86 }
87
88 fn keys(&self) -> Vec<K> {
89 self.inner.keys()
90 }
91
92 fn key_values(&self) -> Dictionary<K, T> {
93 self.inner.key_values()
94 }
95
96 fn lookup(&self, key: &K) -> Option<T> {
97 self.inner.lookup(key)
98 }
99}
100
101impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> ISourceCache<T, K> for SourceCache<T, K> {
102 fn key_selector(&self) -> KeySelector<T, K> {
103 self.key_selector.clone()
104 }
105
106 fn edit(&self, update: &mut dyn FnMut(&mut dyn ISourceUpdater<T, K>)) {
107 self.inner.update_from_source(|updater| update(updater));
108 }
109}
110
111impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IDisposable for SourceCache<T, K> {
112 fn dispose(&self) {
113 self.inner.dispose();
114 }
115}