Skip to main content

ferroui_dynamic_data/list/internal/
immutable_group.rs

1//! `ImmutableGroup<TObject, TGroupKey>` (`List/Internal/ImmutableGroup.cs`).
2
3use crate::list::IGrouping;
4use std::fmt;
5use std::hash::{Hash, Hasher};
6use std::rc::Rc;
7
8struct Inner<T, G> {
9    key: G,
10    items: Vec<T>,
11}
12
13/// The state of a group of a list at one moment (`ImmutableGroup<TObject, TGroupKey>`, the
14/// `IGrouping` of the change sets of `GroupWithImmutableState`): a copy of its items. A clone is
15/// the same state.
16///
17/// Deviation (DEVIATIONS.md, DynamicData): upstream's class is internal and its change sets hold
18/// the interface `IGrouping`; here they hold this type, so it is public.
19pub struct ImmutableGroup<T, G> {
20    inner: Rc<Inner<T, G>>,
21}
22
23impl<T, G> Clone for ImmutableGroup<T, G> {
24    fn clone(&self) -> Self {
25        Self { inner: self.inner.clone() }
26    }
27}
28
29impl<T, G> ImmutableGroup<T, G> {
30    /// The state of the group `key` with the items (`ImmutableGroup(TGroupKey, IList<TObject>)`,
31    /// which copies them).
32    pub(crate) fn new(key: G, items: Vec<T>) -> Self {
33        Self { inner: Rc::new(Inner { key, items }) }
34    }
35
36    /// Whether `self` and `other` are the same state (`ReferenceEquals`).
37    pub fn ptr_eq(&self, other: &Self) -> bool {
38        Rc::ptr_eq(&self.inner, &other.inner)
39    }
40}
41
42impl<T: Clone, G> IGrouping<T, G> for ImmutableGroup<T, G> {
43    fn count(&self) -> usize {
44        self.inner.items.len()
45    }
46
47    fn items(&self) -> Vec<T> {
48        self.inner.items.clone()
49    }
50
51    fn key(&self) -> &G {
52        &self.inner.key
53    }
54}
55
56impl<T, G: PartialEq> PartialEq for ImmutableGroup<T, G> {
57    /// States of the same group key are equal (`Equals`).
58    fn eq(&self, other: &Self) -> bool {
59        Rc::ptr_eq(&self.inner, &other.inner) || self.inner.key == other.inner.key
60    }
61}
62
63impl<T, G: Eq> Eq for ImmutableGroup<T, G> {}
64
65impl<T, G: Hash> Hash for ImmutableGroup<T, G> {
66    /// The hash of the group key (`GetHashCode`).
67    fn hash<H: Hasher>(&self, state: &mut H) {
68        self.inner.key.hash(state);
69    }
70}
71
72impl<T, G: fmt::Display> fmt::Display for ImmutableGroup<T, G> {
73    /// `ToString`: `Grouping for: {Key} ({Count} items)`.
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(f, "Grouping for: {} ({} items)", self.inner.key, self.inner.items.len())
76    }
77}
78
79impl<T, G: fmt::Debug> fmt::Debug for ImmutableGroup<T, G> {
80    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81        write!(f, "Grouping for: {:?} ({} items)", self.inner.key, self.inner.items.len())
82    }
83}