Skip to main content

ferroui_dynamic_data/cache/internal/
key_value_collection.rs

1//! `KeyValueCollection<TObject, TKey>` (`Cache/Internal/KeyValueCollection.cs`).
2
3use super::KeyValueComparer;
4use crate::cache::{IKeyValueCollection, SortOptimisations, SortReason};
5use std::fmt;
6use std::ops::Deref;
7use std::rc::Rc;
8
9/// The sorted pairs of a key and an item of a sorted change set (`KeyValueCollection<TObject,
10/// TKey>`), with the comparer that sorted them and the reason of the sort.
11///
12/// Deviation (DEVIATIONS.md, DynamicData): a pair is the tuple `(key, item)`, upstream's
13/// `KeyValuePair<TKey, TObject>`; `.0` is `Key` and `.1` is `Value`. The pairs are shared, so
14/// cloning a collection is cheap.
15pub struct KeyValueCollection<T, K> {
16    items: Rc<[(K, T)]>,
17    comparer: KeyValueComparer<T, K>,
18    sort_reason: SortReason,
19    optimisations: SortOptimisations,
20}
21
22impl<T, K> Clone for KeyValueCollection<T, K> {
23    fn clone(&self) -> Self {
24        Self { items: self.items.clone(), comparer: self.comparer.clone(), sort_reason: self.sort_reason, optimisations: self.optimisations }
25    }
26}
27
28impl<T, K> Default for KeyValueCollection<T, K> {
29    /// An empty collection, compared by the keys (`KeyValueCollection()`).
30    fn default() -> Self {
31        Self::empty()
32    }
33}
34
35impl<T, K> KeyValueCollection<T, K> {
36    /// A collection of `items`, sorted by `comparer` for `sort_reason`
37    /// (`KeyValueCollection(IReadOnlyCollection<KeyValuePair<TKey, TObject>>, IComparer, SortReason,
38    /// SortOptimisations)`).
39    pub fn new(items: Vec<(K, T)>, comparer: KeyValueComparer<T, K>, sort_reason: SortReason, optimisations: SortOptimisations) -> Self {
40        Self { items: Rc::from(items), comparer, sort_reason, optimisations }
41    }
42
43    /// An empty collection (`KeyValueCollection()`): no optimisations, compared by the keys.
44    pub fn empty() -> Self {
45        Self::new(Vec::new(), KeyValueComparer::new(None), SortReason::InitialLoad, SortOptimisations::NONE)
46    }
47
48    /// The comparer of the pairs (`Comparer`).
49    pub fn comparer(&self) -> &KeyValueComparer<T, K> {
50        &self.comparer
51    }
52
53    /// The number of pairs (`Count`).
54    pub fn count(&self) -> usize {
55        self.items.len()
56    }
57
58    /// The optimisations of the sort (`Optimisations`).
59    pub fn optimisations(&self) -> SortOptimisations {
60        self.optimisations
61    }
62
63    /// The reason of the sort (`SortReason`).
64    pub fn sort_reason(&self) -> SortReason {
65        self.sort_reason
66    }
67
68    /// The pairs, in order.
69    pub fn items(&self) -> &[(K, T)] {
70        &self.items
71    }
72
73    /// The pairs as a list of their own (`ToList`).
74    pub fn to_vec(&self) -> Vec<(K, T)>
75    where
76        T: Clone,
77        K: Clone,
78    {
79        self.items.to_vec()
80    }
81
82    /// The items, in order (`Select(kv => kv.Value)`).
83    pub fn values(&self) -> impl Iterator<Item = &T> {
84        self.items.iter().map(|(_, value)| value)
85    }
86
87    /// The keys, in order (`Select(kv => kv.Key)`).
88    pub fn keys(&self) -> impl Iterator<Item = &K> {
89        self.items.iter().map(|(key, _)| key)
90    }
91
92    /// Whether `self` and `other` share their pairs (`ReferenceEquals` of upstream's collections).
93    pub fn ptr_eq(&self, other: &Self) -> bool {
94        Rc::ptr_eq(&self.items, &other.items)
95    }
96}
97
98impl<T, K> Deref for KeyValueCollection<T, K> {
99    type Target = [(K, T)];
100
101    fn deref(&self) -> &Self::Target {
102        &self.items
103    }
104}
105
106impl<'a, T, K> IntoIterator for &'a KeyValueCollection<T, K> {
107    type Item = &'a (K, T);
108    type IntoIter = std::slice::Iter<'a, (K, T)>;
109
110    fn into_iter(self) -> Self::IntoIter {
111        self.items.iter()
112    }
113}
114
115impl<T: PartialEq, K: PartialEq> PartialEq for KeyValueCollection<T, K> {
116    /// The same pairs in the same order (`SequenceEqual`).
117    fn eq(&self, other: &Self) -> bool {
118        self.items == other.items
119    }
120}
121
122impl<T: fmt::Debug, K: fmt::Debug> fmt::Debug for KeyValueCollection<T, K> {
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        f.debug_list().entries(self.items.iter()).finish()
125    }
126}
127
128impl<T, K> IKeyValueCollection<T, K> for KeyValueCollection<T, K> {
129    fn comparer(&self) -> &KeyValueComparer<T, K> {
130        &self.comparer
131    }
132
133    fn optimisations(&self) -> SortOptimisations {
134        self.optimisations
135    }
136
137    fn sort_reason(&self) -> SortReason {
138        self.sort_reason
139    }
140
141    fn items(&self) -> &[(K, T)] {
142        &self.items
143    }
144}