1use crate::cache::internal::{default_equality_comparer, merge_change_sets, sources_observable};
18use crate::cache::ChangeSet;
19use ferroui_reactive::concurrency::IScheduler;
20use ferroui_system::IObservable;
21use std::cmp::Ordering;
22use std::hash::Hash;
23use std::rc::Rc;
24
25macro_rules! merge_change_sets_methods {
26 () => {
27 fn merge_change_sets(
31 &self,
32 other: std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>,
33 ) -> std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>
34 where
35 T: PartialEq,
36 {
37 crate::cache::ops::merge_change_sets::merge_sources(vec![self.change_sets(), other], None, None, None, true)
38 }
39
40 fn merge_change_sets_with_comparer(
43 &self,
44 other: std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>,
45 equality_comparer: impl Fn(&T, &T) -> bool + 'static,
46 ) -> std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>> {
47 crate::cache::ops::merge_change_sets::merge_sources_with(vec![self.change_sets(), other], std::rc::Rc::new(equality_comparer), None, None, true)
48 }
49
50 fn merge_change_sets_ordered_by(
53 &self,
54 other: std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>,
55 comparer: std::rc::Rc<dyn Fn(&T, &T) -> std::cmp::Ordering>,
56 ) -> std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>
57 where
58 T: PartialEq,
59 {
60 crate::cache::ops::merge_change_sets::merge_sources(vec![self.change_sets(), other], None, Some(comparer), None, true)
61 }
62
63 fn merge_change_sets_with(
69 &self,
70 other: std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>,
71 equality_comparer: Option<std::rc::Rc<dyn Fn(&T, &T) -> bool>>,
72 comparer: Option<std::rc::Rc<dyn Fn(&T, &T) -> std::cmp::Ordering>>,
73 scheduler: Option<std::rc::Rc<dyn ferroui_reactive::concurrency::IScheduler>>,
74 completable: bool,
75 ) -> std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>
76 where
77 T: PartialEq,
78 {
79 crate::cache::ops::merge_change_sets::merge_sources(vec![self.change_sets(), other], equality_comparer, comparer, scheduler, completable)
80 }
81
82 fn merge_change_sets_many(
86 &self,
87 others: Vec<std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>>,
88 ) -> std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>
89 where
90 T: PartialEq,
91 {
92 let mut sources = vec![self.change_sets()];
93 sources.extend(others);
94 crate::cache::ops::merge_change_sets::merge_sources(sources, None, None, None, true)
95 }
96
97 fn merge_change_sets_many_with(
101 &self,
102 others: Vec<std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>>,
103 equality_comparer: Option<std::rc::Rc<dyn Fn(&T, &T) -> bool>>,
104 comparer: Option<std::rc::Rc<dyn Fn(&T, &T) -> std::cmp::Ordering>>,
105 scheduler: Option<std::rc::Rc<dyn ferroui_reactive::concurrency::IScheduler>>,
106 completable: bool,
107 ) -> std::rc::Rc<dyn ferroui_system::IObservable<crate::cache::ChangeSet<T, K>>>
108 where
109 T: PartialEq,
110 {
111 let mut sources = vec![self.change_sets()];
112 sources.extend(others);
113 crate::cache::ops::merge_change_sets::merge_sources(sources, equality_comparer, comparer, scheduler, completable)
114 }
115 };
116}
117pub(crate) use merge_change_sets_methods;
118
119pub(crate) fn merge_sources<T: Clone + PartialEq + 'static, K: Eq + Hash + Clone + 'static>(
121 sources: Vec<Rc<dyn IObservable<ChangeSet<T, K>>>>,
122 equality_comparer: Option<Rc<dyn Fn(&T, &T) -> bool>>,
123 comparer: Option<Rc<dyn Fn(&T, &T) -> Ordering>>,
124 scheduler: Option<Rc<dyn IScheduler>>,
125 completable: bool,
126) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
127 merge_sources_with(sources, equality_comparer.unwrap_or_else(default_equality_comparer), comparer, scheduler, completable)
128}
129
130pub(crate) fn merge_sources_with<T: Clone + 'static, K: Eq + Hash + Clone + 'static>(
132 sources: Vec<Rc<dyn IObservable<ChangeSet<T, K>>>>,
133 equality_comparer: Rc<dyn Fn(&T, &T) -> bool>,
134 comparer: Option<Rc<dyn Fn(&T, &T) -> Ordering>>,
135 scheduler: Option<Rc<dyn IScheduler>>,
136 completable: bool,
137) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
138 merge_change_sets(sources_observable(sources, completable, scheduler), equality_comparer, comparer)
139}
140
141pub trait CacheChangeSetSourcesEx<T, K> {
146 fn merge_change_sets(&self) -> Rc<dyn IObservable<ChangeSet<T, K>>>
149 where
150 T: PartialEq;
151
152 fn merge_change_sets_with_comparer(&self, equality_comparer: impl Fn(&T, &T) -> bool + 'static) -> Rc<dyn IObservable<ChangeSet<T, K>>>;
154
155 fn merge_change_sets_ordered_by(&self, comparer: Rc<dyn Fn(&T, &T) -> Ordering>) -> Rc<dyn IObservable<ChangeSet<T, K>>>
158 where
159 T: PartialEq;
160
161 fn merge_change_sets_with(
165 &self,
166 equality_comparer: Option<Rc<dyn Fn(&T, &T) -> bool>>,
167 comparer: Option<Rc<dyn Fn(&T, &T) -> Ordering>>,
168 scheduler: Option<Rc<dyn IScheduler>>,
169 completable: bool,
170 ) -> Rc<dyn IObservable<ChangeSet<T, K>>>
171 where
172 T: PartialEq;
173}
174
175impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> CacheChangeSetSourcesEx<T, K> for [Rc<dyn IObservable<ChangeSet<T, K>>>] {
176 fn merge_change_sets(&self) -> Rc<dyn IObservable<ChangeSet<T, K>>>
177 where
178 T: PartialEq,
179 {
180 merge_sources(self.to_vec(), None, None, None, true)
181 }
182
183 fn merge_change_sets_with_comparer(&self, equality_comparer: impl Fn(&T, &T) -> bool + 'static) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
184 merge_sources_with(self.to_vec(), Rc::new(equality_comparer), None, None, true)
185 }
186
187 fn merge_change_sets_ordered_by(&self, comparer: Rc<dyn Fn(&T, &T) -> Ordering>) -> Rc<dyn IObservable<ChangeSet<T, K>>>
188 where
189 T: PartialEq,
190 {
191 merge_sources(self.to_vec(), None, Some(comparer), None, true)
192 }
193
194 fn merge_change_sets_with(
195 &self,
196 equality_comparer: Option<Rc<dyn Fn(&T, &T) -> bool>>,
197 comparer: Option<Rc<dyn Fn(&T, &T) -> Ordering>>,
198 scheduler: Option<Rc<dyn IScheduler>>,
199 completable: bool,
200 ) -> Rc<dyn IObservable<ChangeSet<T, K>>>
201 where
202 T: PartialEq,
203 {
204 merge_sources(self.to_vec(), equality_comparer, comparer, scheduler, completable)
205 }
206}
207
208pub trait ObservableCacheChangeSetsEx<T, K> {
213 fn merge_change_sets(&self) -> Rc<dyn IObservable<ChangeSet<T, K>>>
215 where
216 T: PartialEq;
217
218 fn merge_change_sets_with_comparer(&self, equality_comparer: impl Fn(&T, &T) -> bool + 'static) -> Rc<dyn IObservable<ChangeSet<T, K>>>;
220
221 fn merge_change_sets_ordered_by(&self, comparer: Rc<dyn Fn(&T, &T) -> Ordering>) -> Rc<dyn IObservable<ChangeSet<T, K>>>
223 where
224 T: PartialEq;
225
226 fn merge_change_sets_with(&self, equality_comparer: Option<Rc<dyn Fn(&T, &T) -> bool>>, comparer: Option<Rc<dyn Fn(&T, &T) -> Ordering>>) -> Rc<dyn IObservable<ChangeSet<T, K>>>
229 where
230 T: PartialEq;
231}
232
233impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> ObservableCacheChangeSetsEx<T, K> for Rc<dyn IObservable<Rc<dyn IObservable<ChangeSet<T, K>>>>> {
234 fn merge_change_sets(&self) -> Rc<dyn IObservable<ChangeSet<T, K>>>
235 where
236 T: PartialEq,
237 {
238 merge_change_sets(self.clone(), default_equality_comparer(), None)
239 }
240
241 fn merge_change_sets_with_comparer(&self, equality_comparer: impl Fn(&T, &T) -> bool + 'static) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
242 merge_change_sets(self.clone(), Rc::new(equality_comparer), None)
243 }
244
245 fn merge_change_sets_ordered_by(&self, comparer: Rc<dyn Fn(&T, &T) -> Ordering>) -> Rc<dyn IObservable<ChangeSet<T, K>>>
246 where
247 T: PartialEq,
248 {
249 merge_change_sets(self.clone(), default_equality_comparer(), Some(comparer))
250 }
251
252 fn merge_change_sets_with(&self, equality_comparer: Option<Rc<dyn Fn(&T, &T) -> bool>>, comparer: Option<Rc<dyn Fn(&T, &T) -> Ordering>>) -> Rc<dyn IObservable<ChangeSet<T, K>>>
253 where
254 T: PartialEq,
255 {
256 merge_change_sets(self.clone(), equality_comparer.unwrap_or_else(default_equality_comparer), comparer)
257 }
258}