Skip to main content

ferroui_dynamic_data/cache/
sorted_observable_cache_ex.rs

1//! The operators of the sequences of sorted change sets (the extension methods of
2//! `ObservableCacheEx` that take `IObservable<ISortedChangeSet<TObject, TKey>>`), and the
3//! aggregators of the sorted, paged, virtual and contextual change sets (`Cache/Tests/TestEx.cs`).
4//!
5//! A sorted stream is also a stream of change sets, so it has every operator of
6//! [`ObservableCacheEx`](super::ObservableCacheEx) as well; the methods here have names of their
7//! own so that both traits can be in scope (`as_sorted_aggregator` beside `as_aggregator`,
8//! `top_sorted` beside `top`).
9
10use super::testing::TypedChangeSetAggregator;
11use super::{ChangeSetWithContext, ISortedChangeSet, SortedChangeSet};
12use ferroui_reactive::ObservableExt;
13use ferroui_system::IObservable;
14use std::any::Any;
15use std::hash::Hash;
16use std::rc::Rc;
17
18/// The operators of sorted change sets (`ObservableCacheEx` over `ISortedChangeSet`), for every
19/// sequence of sorted, paged or virtual change sets `C`.
20pub trait SortedObservableCacheEx<T: Clone + 'static, K: Eq + Hash + Clone + 'static, C: ISortedChangeSet<T, K>> {
21    /// The sequence itself.
22    fn sorted_source(&self) -> Rc<dyn IObservable<C>>;
23
24    /// The sequence as plain sorted change sets (the upcast of a paged or virtual change set to
25    /// `ISortedChangeSet<TObject, TKey>`).
26    fn sorted_change_sets(&self) -> Rc<dyn IObservable<SortedChangeSet<T, K>>>;
27
28    /// Records the change sets, the items and the end of the sequence, for tests
29    /// (`TestEx.AsAggregator` of sorted, paged and virtual change sets, which make a
30    /// `SortedChangeSetAggregator`, a `PagedChangeSetAggregator` or a
31    /// `VirtualChangeSetAggregator`).
32    fn as_sorted_aggregator(&self) -> TypedChangeSetAggregator<T, K, C> {
33        TypedChangeSetAggregator::new(self.sorted_source())
34    }
35
36    super::ops::treat_moves_as_remove_add::treat_moves_as_remove_add_methods!();
37    super::ops::update_index::update_index_methods!();
38    super::ops::virtualise_and_page::virtualise_and_page_sorted_methods!();
39}
40
41impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static, C: ISortedChangeSet<T, K>> SortedObservableCacheEx<T, K, C> for Rc<dyn IObservable<C>> {
42    fn sorted_source(&self) -> Rc<dyn IObservable<C>> {
43        self.clone()
44    }
45
46    fn sorted_change_sets(&self) -> Rc<dyn IObservable<SortedChangeSet<T, K>>> {
47        if let Some(sorted) = (self as &dyn Any).downcast_ref::<Rc<dyn IObservable<SortedChangeSet<T, K>>>>() {
48            return sorted.clone();
49        }
50        self.select(|changes: C| changes.to_sorted_change_set())
51    }
52}
53
54/// The aggregator of the change sets with a context (`TestEx.AsAggregator` of
55/// `IObservable<IChangeSet<TObject, TKey, TContext>>`).
56pub trait ContextObservableCacheEx<T: Clone + 'static, K: Eq + Hash + Clone + 'static, X: Clone + 'static> {
57    /// Records the change sets, the items and the end of the sequence, for tests
58    /// (`ChangeSetAggregator<TObject, TKey, TContext>`).
59    fn as_context_aggregator(&self) -> TypedChangeSetAggregator<T, K, ChangeSetWithContext<T, K, X>>;
60}
61
62impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static, X: Clone + 'static> ContextObservableCacheEx<T, K, X> for Rc<dyn IObservable<ChangeSetWithContext<T, K, X>>> {
63    fn as_context_aggregator(&self) -> TypedChangeSetAggregator<T, K, ChangeSetWithContext<T, K, X>> {
64        TypedChangeSetAggregator::new(self.clone())
65    }
66}