ferroui_dynamic_data/cache/internal/
cache_updater.rs1use crate::cache::{ChangeSet, ICache, ICacheUpdater, IQuery, ISourceUpdater};
8use std::cell::RefCell;
9use std::rc::Rc;
10
11pub type KeySelector<T, K> = Rc<dyn Fn(&T) -> K>;
13
14pub(crate) struct CacheUpdater<'a, T, K> {
16 cache: &'a RefCell<dyn ICache<T, K>>,
17 key_selector: Option<&'a KeySelector<T, K>>,
18}
19
20impl<'a, T, K> CacheUpdater<'a, T, K> {
21 pub(crate) fn new(cache: &'a RefCell<dyn ICache<T, K>>, key_selector: Option<&'a KeySelector<T, K>>) -> Self {
22 Self { cache, key_selector }
23 }
24
25 fn key_of(&self, item: &T) -> K {
26 match self.key_selector {
27 Some(selector) => selector(item),
28 None => panic!("A key selector must be specified"),
29 }
30 }
31
32 fn with<R>(&self, action: impl FnOnce(&mut dyn ICache<T, K>) -> R) -> R {
33 action(&mut *self.cache.borrow_mut())
34 }
35}
36
37impl<T, K> IQuery<T, K> for CacheUpdater<'_, T, K> {
38 fn count(&self) -> usize {
39 self.cache.borrow().count()
40 }
41
42 fn items(&self) -> Vec<T> {
43 self.cache.borrow().items()
44 }
45
46 fn keys(&self) -> Vec<K> {
47 self.cache.borrow().keys()
48 }
49
50 fn key_values(&self) -> Vec<(K, T)> {
51 self.cache.borrow().key_values()
52 }
53
54 fn lookup(&self, key: &K) -> Option<T> {
55 self.cache.borrow().lookup(key)
56 }
57}
58
59impl<T, K> ICacheUpdater<T, K> for CacheUpdater<'_, T, K> {
60 fn add_or_update_pairs(&mut self, pairs: &mut dyn Iterator<Item = (K, T)>) {
61 for (key, item) in pairs {
62 self.with(|cache| cache.add_or_update(item, key));
63 }
64 }
65
66 fn add_or_update_with_key(&mut self, item: T, key: K) {
67 self.with(|cache| cache.add_or_update(item, key));
68 }
69
70 fn clear(&mut self) {
71 self.with(|cache| cache.clear());
72 }
73
74 fn clone_changes(&mut self, changes: &ChangeSet<T, K>) {
75 self.with(|cache| cache.clone_changes(changes));
76 }
77
78 fn get_key(&self, item: &T) -> K {
79 self.key_of(item)
80 }
81
82 fn get_key_values(&self, items: &mut dyn Iterator<Item = T>) -> Vec<(K, T)> {
83 items.map(|item| (self.key_of(&item), item)).collect()
84 }
85
86 fn refresh_all(&mut self) {
87 self.with(|cache| cache.refresh_all());
88 }
89
90 fn refresh_keys(&mut self, keys: &mut dyn Iterator<Item = K>) {
91 for key in keys {
92 self.with(|cache| cache.refresh(&key));
93 }
94 }
95
96 fn refresh_key(&mut self, key: &K) {
97 self.with(|cache| cache.refresh(key));
98 }
99
100 fn remove_keys(&mut self, keys: &mut dyn Iterator<Item = K>) {
101 for key in keys {
102 self.with(|cache| cache.remove(&key));
103 }
104 }
105
106 fn remove_key(&mut self, key: &K) {
107 self.with(|cache| cache.remove(key));
108 }
109
110 fn remove_pairs(&mut self, pairs: &mut dyn Iterator<Item = (K, T)>) {
111 for (key, _) in pairs {
112 self.with(|cache| cache.remove(&key));
113 }
114 }
115}
116
117impl<T, K> ISourceUpdater<T, K> for CacheUpdater<'_, T, K> {
118 fn add_or_update_items(&mut self, items: &mut dyn Iterator<Item = T>) {
119 for item in items {
120 self.add_or_update(item);
121 }
122 }
123
124 fn add_or_update_items_with(&mut self, items: &mut dyn Iterator<Item = T>, comparer: &dyn Fn(&T, &T) -> bool) {
125 for item in items {
126 self.add_or_update_with(item, comparer);
127 }
128 }
129
130 fn add_or_update(&mut self, item: T) {
131 let key = self.key_of(&item);
132 self.with(|cache| cache.add_or_update(item, key));
133 }
134
135 fn add_or_update_with(&mut self, item: T, comparer: &dyn Fn(&T, &T) -> bool) {
136 let key = self.key_of(&item);
137 let old = self.cache.borrow().lookup(&key);
138 if let Some(old) = old {
139 if comparer(&old, &item) {
140 return;
141 }
142 }
143 self.with(|cache| cache.add_or_update(item, key));
144 }
145
146 fn load(&mut self, items: &mut dyn Iterator<Item = T>) {
147 self.with(|cache| cache.clear());
148 self.add_or_update_items(items);
149 }
150
151 fn lookup_item(&self, item: &T) -> Option<T> {
152 let key = self.key_of(item);
153 self.cache.borrow().lookup(&key)
154 }
155
156 fn refresh_items(&mut self, items: &mut dyn Iterator<Item = T>) {
157 for item in items {
158 self.refresh_item(&item);
159 }
160 }
161
162 fn refresh_item(&mut self, item: &T) {
163 let key = self.key_of(item);
164 self.with(|cache| cache.refresh(&key));
165 }
166
167 fn remove_items(&mut self, items: &mut dyn Iterator<Item = T>) {
168 for item in items {
169 self.remove_item(&item);
170 }
171 }
172
173 fn remove_item(&mut self, item: &T) {
174 let key = self.key_of(item);
175 self.with(|cache| cache.remove(&key));
176 }
177}