Skip to main content

ferroui_dynamic_data/binding/
read_only_observable_collection.rs

1//! `ReadOnlyObservableCollection<T>` (`System.Collections.ObjectModel`), the read-only view that the
2//! `out` forms of `Bind` and `SortAndBind` hand out.
3//!
4//! Deviation (DEVIATIONS.md, DynamicData): the type belongs to the base library upstream; it lives
5//! here until `ferroui-system` has it. It shares the notifications of the collection it wraps
6//! rather than raising its own with itself as the sender.
7
8use super::ObservableCollectionExtended;
9use ferroui_system::collections::object_model::{CollectionChangedHandler, ObservableCollection};
10use ferroui_system::collections::specialized::{CollectionChange, INotifyCollectionChanged};
11use ferroui_system::component_model::INotifyPropertyChanged;
12use ferroui_system::events::Event;
13use std::cell::Ref;
14use std::fmt;
15use std::rc::Rc;
16
17/// A read-only view of an observable collection (`ReadOnlyObservableCollection<T>`).
18pub struct ReadOnlyObservableCollection<T> {
19    collection: ObservableCollection<T>,
20}
21
22impl<T> Clone for ReadOnlyObservableCollection<T> {
23    fn clone(&self) -> Self {
24        Self { collection: self.collection.clone() }
25    }
26}
27
28impl<T> PartialEq for ReadOnlyObservableCollection<T> {
29    /// A view of the same collection.
30    fn eq(&self, other: &Self) -> bool {
31        self.collection == other.collection
32    }
33}
34
35impl<T: Clone + PartialEq + fmt::Debug + 'static> fmt::Debug for ReadOnlyObservableCollection<T> {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        f.debug_list().entries(self.collection.items().iter()).finish()
38    }
39}
40
41impl<T: Clone + PartialEq + 'static> ReadOnlyObservableCollection<T> {
42    /// The view of `collection` (`ReadOnlyObservableCollection(ObservableCollection<T>)`).
43    pub fn new(collection: ObservableCollection<T>) -> Self {
44        Self { collection }
45    }
46
47    /// The collection that the view shows.
48    pub(crate) fn collection(&self) -> &ObservableCollection<T> {
49        &self.collection
50    }
51
52    /// Adds a handler of the typed change notifications; returns the token that removes it
53    /// (`CollectionChanged +=`).
54    pub fn add_collection_changed(&self, handler: Rc<CollectionChangedHandler<T>>) -> u64 {
55        self.collection.add_collection_changed(handler)
56    }
57
58    /// Removes a handler (`CollectionChanged -=`).
59    pub fn remove_collection_changed(&self, token: u64) -> bool {
60        self.collection.remove_collection_changed(token)
61    }
62
63    /// The number of items (`Count`).
64    pub fn count(&self) -> usize {
65        self.collection.count()
66    }
67
68    pub fn is_empty(&self) -> bool {
69        self.collection.is_empty()
70    }
71
72    /// The item at `index` (the indexer).
73    pub fn get(&self, index: usize) -> T {
74        self.collection.get(index)
75    }
76
77    /// The items, borrowed.
78    pub fn items(&self) -> Ref<'_, Vec<T>> {
79        self.collection.items()
80    }
81
82    /// A copy of the items.
83    pub fn to_vec(&self) -> Vec<T> {
84        self.collection.to_vec()
85    }
86
87    /// Whether the collection has `item` (`Contains`).
88    pub fn contains(&self, item: &T) -> bool {
89        self.collection.contains(item)
90    }
91
92    /// The index of `item` (`IndexOf`).
93    pub fn index_of(&self, item: &T) -> Option<usize> {
94        self.collection.index_of(item)
95    }
96}
97
98impl<T: Clone + PartialEq + 'static> From<ObservableCollection<T>> for ReadOnlyObservableCollection<T> {
99    fn from(collection: ObservableCollection<T>) -> Self {
100        Self::new(collection)
101    }
102}
103
104impl<T: Clone + PartialEq + 'static> From<&ObservableCollectionExtended<T>> for ReadOnlyObservableCollection<T> {
105    /// The view of the collection (`new ReadOnlyObservableCollection<T>(observableCollectionExtended)`).
106    fn from(collection: &ObservableCollectionExtended<T>) -> Self {
107        Self::new(collection.collection().clone())
108    }
109}
110
111impl<T> INotifyCollectionChanged for ReadOnlyObservableCollection<T> {
112    fn collection_changed(&self) -> &Event<CollectionChange> {
113        self.collection.collection_changed()
114    }
115}
116
117impl<T> INotifyPropertyChanged for ReadOnlyObservableCollection<T> {
118    fn property_changed(&self) -> &Event<str> {
119        self.collection.property_changed()
120    }
121}