Skip to main content

ferroui_dynamic_data/cache/
observable_cache_ex.rs

1//! `ObservableCacheEx` (`Cache/ObservableCacheEx*.cs`): the operators of the sequences of change
2//! sets of caches.
3//!
4//! Each upstream operator is a provided method, from the `*_methods!` macro of its module in
5//! `ops/`. The trait is implemented for every sequence of change sets of any form ([`IChangeSet`]),
6//! as upstream's extension methods take the interface (docs/porting/reactive.md, section 5.4).
7//!
8//! Naming (DEVIATIONS.md, DynamicData): an operator whose name is that of an operator of
9//! `ferroui_reactive::ObservableExt`, which applies to the same sequences, takes the suffix `_cache`
10//! (`and_cache`, `cast_cache`, `of_type_cache`, `switch_cache`, `count_cache`, `is_empty_cache`,
11//! `sum_cache`), so that both traits can be in scope. The LINQ-named aliases of
12//! `ObservableCacheAlias` (`Select`, `Where`, `SelectMany`) are not ported for the same reason.
13
14use super::{ChangeSet, IChangeSet};
15use ferroui_reactive::ObservableExt;
16use ferroui_system::IObservable;
17use std::any::Any;
18use std::hash::Hash;
19use std::rc::Rc;
20
21/// The operators of caches (`ObservableCacheEx`).
22pub trait ObservableCacheEx<T: Clone + 'static, K: Eq + Hash + Clone + 'static> {
23    /// The sequence as plain change sets (the upcast of a sorted, paged or contextual change set to
24    /// `IChangeSet<TObject, TKey>`).
25    fn change_sets(&self) -> Rc<dyn IObservable<ChangeSet<T, K>>>;
26
27    super::ops::and::and_methods!();
28    super::ops::async_dispose_many::async_dispose_many_methods!();
29    super::ops::except::except_methods!();
30    super::ops::full_join::full_join_methods!();
31    super::ops::full_join_many::full_join_many_methods!();
32    super::ops::inner_join::inner_join_methods!();
33    super::ops::inner_join_many::inner_join_many_methods!();
34    super::ops::left_join::left_join_methods!();
35    super::ops::left_join_many::left_join_many_methods!();
36    super::ops::or::or_methods!();
37    super::ops::right_join::right_join_methods!();
38    super::ops::right_join_many::right_join_many_methods!();
39    super::ops::transform_async::transform_async_methods!();
40    super::ops::transform_many_async::transform_many_async_methods!();
41    super::ops::transform_many_safe_async::transform_many_safe_async_methods!();
42    super::ops::transform_safe_async::transform_safe_async_methods!();
43    super::ops::xor::xor_methods!();
44
45    super::ops::adapt::adapt_methods!();
46    super::ops::auto_refresh::auto_refresh_methods!();
47    super::ops::auto_refresh_on_observable::auto_refresh_on_observable_methods!();
48    super::ops::batch::batch_methods!();
49    super::ops::batch_if::batch_if_methods!();
50    super::ops::bind::bind_methods!();
51    super::ops::bind_to_observable_list::bind_to_observable_list_methods!();
52    super::ops::buffer_initial::buffer_initial_methods!();
53    super::ops::cast::cast_methods!();
54    super::ops::change_key::change_key_methods!();
55    super::ops::clone::clone_methods!();
56    super::ops::convert::convert_methods!();
57    super::ops::defer_until_loaded::defer_until_loaded_methods!();
58    super::ops::dispose_many::dispose_many_methods!();
59    super::ops::distinct_values::distinct_values_methods!();
60    super::ops::ensure_unique_keys::ensure_unique_keys_methods!();
61    super::ops::expire_after::expire_after_methods!();
62    super::ops::filter_immutable::filter_immutable_methods!();
63    super::ops::filter_on_observable::filter_on_observable_methods!();
64    super::ops::flatten::flatten_methods!();
65    super::ops::for_each_change::for_each_change_methods!();
66    super::ops::group::group_methods!();
67    super::ops::group_on_observable::group_on_observable_methods!();
68    super::ops::group_on_property::group_on_property_methods!();
69    super::ops::group_on_property_with_immutable_state::group_on_property_with_immutable_state_methods!();
70    super::ops::group_with_immutable_state::group_with_immutable_state_methods!();
71    super::ops::ignore_same_reference_update::ignore_same_reference_update_methods!();
72    super::ops::ignore_update_when::ignore_update_when_methods!();
73    super::ops::include_update_when::include_update_when_methods!();
74    super::ops::invoke_evaluate::invoke_evaluate_methods!();
75    super::ops::limit_size_to::limit_size_to_methods!();
76    super::ops::merge_change_sets::merge_change_sets_methods!();
77    super::ops::merge_many::merge_many_methods!();
78    super::ops::merge_many_change_sets::merge_many_change_sets_methods!();
79    super::ops::merge_many_items::merge_many_items_methods!();
80    super::ops::of_type::of_type_methods!();
81    super::ops::on_item_added::on_item_added_methods!();
82    super::ops::on_item_refreshed::on_item_refreshed_methods!();
83    super::ops::on_item_removed::on_item_removed_methods!();
84    super::ops::on_item_updated::on_item_updated_methods!();
85    super::ops::populate_into::populate_into_methods!();
86    super::ops::query_when_changed::query_when_changed_methods!();
87    super::ops::ref_count::ref_count_methods!();
88    super::ops::remove_key::remove_key_methods!();
89    super::ops::skip_initial::skip_initial_methods!();
90    super::ops::sort::sort_methods!();
91    super::ops::sort_and_bind::sort_and_bind_methods!();
92    super::ops::sort_by::sort_by_methods!();
93    super::ops::start_with_empty::start_with_empty_methods!();
94    super::ops::start_with_item::start_with_item_methods!();
95    super::ops::subscribe_many::subscribe_many_methods!();
96    super::ops::suppress_refresh::suppress_refresh_methods!();
97    super::ops::to_collection::to_collection_methods!();
98    super::ops::to_observable_optional::to_observable_optional_methods!();
99    super::ops::to_sorted_collection::to_sorted_collection_methods!();
100    super::ops::transform::transform_methods!();
101    super::ops::transform_immutable::transform_immutable_methods!();
102    super::ops::transform_many::transform_many_methods!();
103    super::ops::transform_on_observable::transform_on_observable_methods!();
104    super::ops::transform_safe::transform_safe_methods!();
105    super::ops::transform_to_tree::transform_to_tree_methods!();
106    super::ops::transform_with_inline_update::transform_with_inline_update_methods!();
107    super::ops::true_for_all::true_for_all_methods!();
108    super::ops::true_for_any::true_for_any_methods!();
109    super::ops::virtualise_and_page::virtualise_and_page_methods!();
110    super::ops::watch::watch_methods!();
111    super::ops::watch_value::watch_value_methods!();
112    super::ops::when_any_property_changed::when_any_property_changed_methods!();
113    super::ops::when_property_changed::when_property_changed_methods!();
114    super::ops::when_value_changed::when_value_changed_methods!();
115    super::ops::where_reasons_are::where_reasons_are_methods!();
116    super::ops::where_reasons_are_not::where_reasons_are_not_methods!();
117
118    super::ops::as_aggregator::as_aggregator_methods!();
119    super::ops::as_observable_cache::as_observable_cache_methods!();
120    super::ops::collect_update_stats::collect_update_stats_methods!();
121    super::ops::filter::filter_methods!();
122    super::ops::not_empty::not_empty_methods!();
123}
124
125impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static, C: IChangeSet<T, K>> ObservableCacheEx<T, K> for Rc<dyn IObservable<C>> {
126    fn change_sets(&self) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
127        if let Some(plain) = (self as &dyn Any).downcast_ref::<Rc<dyn IObservable<ChangeSet<T, K>>>>() {
128            return plain.clone();
129        }
130        self.select(|changes: C| changes.change_set().clone())
131    }
132}