zerodds_wire/
map_entries.rs1use alloc::vec::Vec;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
17pub struct MapEntry<K, V> {
18 pub key: K,
20 pub value: V,
22}
23
24impl<K, V> MapEntry<K, V> {
25 #[must_use]
27 pub const fn new(key: K, value: V) -> Self {
28 Self { key, value }
29 }
30}
31
32pub trait WireMap<K, V> {
34 fn entry_count(&self) -> usize;
36
37 fn try_visit<E, F: FnMut(&K, &V) -> Result<(), E>>(&self, visit: F) -> Result<(), E>;
42}
43
44impl<K, V> WireMap<K, V> for alloc::collections::BTreeMap<K, V> {
45 fn entry_count(&self) -> usize {
46 self.len()
47 }
48
49 fn try_visit<E, F: FnMut(&K, &V) -> Result<(), E>>(&self, mut visit: F) -> Result<(), E> {
50 for (key, value) in self {
51 visit(key, value)?;
52 }
53 Ok(())
54 }
55}
56
57impl<K, V> WireMap<K, V> for [MapEntry<K, V>] {
58 fn entry_count(&self) -> usize {
59 self.len()
60 }
61
62 fn try_visit<E, F: FnMut(&K, &V) -> Result<(), E>>(&self, mut visit: F) -> Result<(), E> {
63 for entry in self {
64 visit(&entry.key, &entry.value)?;
65 }
66 Ok(())
67 }
68}
69
70impl<K, V> WireMap<K, V> for Vec<MapEntry<K, V>> {
71 fn entry_count(&self) -> usize {
72 self.len()
73 }
74
75 fn try_visit<E, F: FnMut(&K, &V) -> Result<(), E>>(&self, visit: F) -> Result<(), E> {
76 self.as_slice().try_visit(visit)
77 }
78}
79
80#[derive(Debug, Clone, Copy)]
83pub struct AscendingKey<'a, K, V>(pub &'a [MapEntry<K, V>]);
84
85impl<K: Ord, V> WireMap<K, V> for AscendingKey<'_, K, V> {
86 fn entry_count(&self) -> usize {
87 self.0.len()
88 }
89
90 fn try_visit<E, F: FnMut(&K, &V) -> Result<(), E>>(&self, mut visit: F) -> Result<(), E> {
91 let mut order: Vec<&MapEntry<K, V>> = self.0.iter().collect();
92 order.sort_by(|left, right| left.key.cmp(&right.key));
93 for entry in order {
94 visit(&entry.key, &entry.value)?;
95 }
96 Ok(())
97 }
98}
99
100#[cfg(test)]
101#[allow(clippy::unwrap_used)]
102mod tests {
103 use super::*;
104 use alloc::vec;
105
106 #[test]
107 fn a_vec_is_visited_in_the_order_it_holds_and_ascending_key_sorts_a_copy() {
108 let held = vec![
109 MapEntry::new(3, 'c'),
110 MapEntry::new(1, 'a'),
111 MapEntry::new(2, 'b'),
112 ];
113 let mut seen = Vec::new();
114 held.try_visit::<(), _>(|key, _| {
115 seen.push(*key);
116 Ok(())
117 })
118 .unwrap();
119 assert_eq!(seen, [3, 1, 2]);
120 let mut sorted = Vec::new();
121 AscendingKey(&held)
122 .try_visit::<(), _>(|key, _| {
123 sorted.push(*key);
124 Ok(())
125 })
126 .unwrap();
127 assert_eq!(sorted, [1, 2, 3]);
128 assert_eq!(held[0].key, 3, "the held entries are not reordered");
129 }
130}