Skip to main content

tree_table/types/
max_map.rs

1use crate::CellAlign;
2use crate::CellBorders;
3use crate::CellProps;
4use crate::Checkbox;
5use crate::DataFormat;
6use crate::Dropdown;
7use crate::Highlight;
8use crate::Note;
9use crate::ProgressBar;
10use crate::TableCell;
11use crate::Val;
12use alloc::vec::Vec;
13use hashbrown::HashMap;
14use hashbrown::hash_map::Entry;
15
16#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
17#[cfg_attr(feature = "tsify", tsify(from_wasm_abi))]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[derive(Debug, Clone, PartialEq)]
20pub struct MaxMap<T> {
21    pub hm: HashMap<usize, T>,
22    pub maxk: Option<usize>,
23}
24
25pub struct MaxMapKeys<'a, T> {
26    map: &'a MaxMap<T>,
27    current: usize,
28    end: usize,
29}
30
31impl<'a, T> Iterator for MaxMapKeys<'a, T> {
32    type Item = usize;
33
34    fn next(&mut self) -> Option<Self::Item> {
35        while self.current <= self.end {
36            let key = self.current;
37            self.current += 1;
38            if self.map.hm.contains_key(&key) {
39                return Some(key);
40            }
41        }
42        None
43    }
44}
45
46pub struct MaxMapIter<'a, T> {
47    map: &'a MaxMap<T>,
48    current: usize,
49    end: usize,
50}
51
52impl<'a, T> Iterator for MaxMapIter<'a, T> {
53    type Item = (usize, &'a T);
54
55    fn next(&mut self) -> Option<Self::Item> {
56        while self.current <= self.end {
57            let key = self.current;
58            self.current += 1;
59            if let Some(value) = self.map.hm.get(&key) {
60                return Some((key, value));
61            }
62        }
63        None
64    }
65}
66
67pub struct MaxMapValues<'a, T> {
68    iter: MaxMapIter<'a, T>,
69}
70
71impl<'a, T> Iterator for MaxMapValues<'a, T> {
72    type Item = &'a T;
73
74    fn next(&mut self) -> Option<Self::Item> {
75        self.iter.next().map(|(_, v)| v)
76    }
77}
78
79pub struct MaxMapIntoIter<T> {
80    map: MaxMap<T>,
81    keys: Vec<usize>,
82    index: usize,
83}
84
85impl<T> Iterator for MaxMapIntoIter<T> {
86    type Item = (usize, T);
87
88    fn next(&mut self) -> Option<Self::Item> {
89        if self.index < self.keys.len() {
90            let key = self.keys[self.index];
91            self.index += 1;
92            if let Some(value) = self.map.hm.remove(&key) {
93                return Some((key, value));
94            }
95        }
96        None
97    }
98}
99
100impl<T> MaxMap<T> {
101    pub fn new() -> Self {
102        MaxMap {
103            hm: HashMap::new(),
104            maxk: None,
105        }
106    }
107
108    pub fn insert(&mut self, k: usize, v: T) {
109        self.hm.insert(k, v);
110        self.maxk = Some(self.maxk.map_or(k, |max| max.max(k)));
111    }
112
113    pub fn max_removed(&mut self) {
114        if !self.hm.is_empty() {
115            for k in (0..=self.maxk.unwrap_or(0)).rev() {
116                if self.hm.contains_key(&k) {
117                    self.maxk = Some(k);
118                    break;
119                }
120            }
121        } else {
122            self.maxk = None;
123        }
124    }
125
126    pub fn get(&self, key: &usize) -> Option<&T> {
127        self.hm.get(key)
128    }
129
130    pub fn contains_key(&self, key: &usize) -> bool {
131        self.hm.contains_key(key)
132    }
133
134    pub fn len(&self) -> usize {
135        self.hm.len()
136    }
137
138    pub fn is_empty(&self) -> bool {
139        self.hm.is_empty()
140    }
141
142    pub fn get_maxk(&self) -> Option<usize> {
143        self.maxk
144    }
145
146    pub fn iter(&self) -> MaxMapIter<'_, T> {
147        let end = self.maxk.unwrap_or(0);
148        MaxMapIter {
149            map: self,
150            current: 0,
151            end,
152        }
153    }
154
155    pub fn for_each_mut<F>(&mut self, mut f: F)
156    where
157        F: FnMut(usize, &mut T),
158    {
159        if let Some(maxk) = self.maxk {
160            for k in 0..=maxk {
161                if let Some(value) = self.hm.get_mut(&k) {
162                    f(k, value);
163                }
164            }
165        }
166    }
167
168    pub fn keys(&self) -> MaxMapKeys<'_, T> {
169        let end = self.maxk.unwrap_or(0);
170        MaxMapKeys {
171            map: self,
172            current: 0,
173            end,
174        }
175    }
176
177    pub fn values(&self) -> MaxMapValues<'_, T> {
178        MaxMapValues { iter: self.iter() }
179    }
180
181    pub fn entry(&mut self, key: usize) -> Entry<'_, usize, T, hashbrown::DefaultHashBuilder> {
182        self.hm.entry(key)
183    }
184
185    pub fn get_mut(&mut self, key: &usize) -> Option<&mut T> {
186        self.hm.get_mut(key)
187    }
188
189    pub fn remove(&mut self, key: &usize) -> Option<T> {
190        let result = self.hm.remove(key);
191        if result.is_some() && self.maxk == Some(*key) {
192            self.max_removed();
193        }
194        result
195    }
196
197    pub fn clear(&mut self) {
198        self.hm.clear();
199        self.maxk = None;
200    }
201
202    pub fn drain(&mut self) -> hashbrown::hash_map::Drain<'_, usize, T> {
203        self.maxk = None;
204        self.hm.drain()
205    }
206
207    pub fn retain<F>(&mut self, f: F)
208    where
209        F: FnMut(&usize, &mut T) -> bool,
210    {
211        self.hm.retain(f);
212        if !self.hm.is_empty() && self.maxk.is_some() {
213            self.max_removed();
214        } else {
215            self.maxk = None;
216        }
217    }
218}
219
220impl<T> IntoIterator for MaxMap<T> {
221    type Item = (usize, T);
222    type IntoIter = MaxMapIntoIter<T>;
223
224    fn into_iter(self) -> Self::IntoIter {
225        let keys: Vec<usize> = (0..=self.maxk.unwrap_or(0))
226            .filter(|k| self.hm.contains_key(k))
227            .collect();
228        MaxMapIntoIter {
229            map: self,
230            keys,
231            index: 0,
232        }
233    }
234}
235
236impl<'a, T> IntoIterator for &'a MaxMap<T> {
237    type Item = (usize, &'a T);
238    type IntoIter = MaxMapIter<'a, T>;
239
240    fn into_iter(self) -> Self::IntoIter {
241        self.iter()
242    }
243}
244
245macro_rules! impl_set_prop_maxmap {
246    ($prop:ident, $ty:ty) => {
247        #[inline]
248        pub fn $prop(&mut self, pos: usize, prop: Option<$ty>, empty_val: &Val) {
249            self.hm
250                .entry(pos)
251                .or_insert(TableCell {
252                    val: empty_val.clone(),
253                    props: None,
254                })
255                .props
256                .get_or_insert_with(CellProps::new)
257                .$prop = prop;
258            self.maxk = Some(self.maxk.map_or(pos, |max| max.max(pos)));
259        }
260    };
261}
262
263impl MaxMap<TableCell> {
264    impl_set_prop_maxmap!(align, CellAlign);
265    impl_set_prop_maxmap!(borders, CellBorders);
266    impl_set_prop_maxmap!(checkbox, Checkbox);
267    impl_set_prop_maxmap!(data_format, DataFormat);
268    impl_set_prop_maxmap!(dropdown, Dropdown);
269    impl_set_prop_maxmap!(highlight, Highlight);
270    impl_set_prop_maxmap!(note, Note);
271    impl_set_prop_maxmap!(progress_bar, ProgressBar);
272
273    #[inline]
274    pub fn readonly(&mut self, pos: usize, prop: bool, empty_val: &Val) {
275        self.hm
276            .entry(pos)
277            .or_insert(TableCell {
278                val: empty_val.clone(),
279                props: None,
280            })
281            .props
282            .get_or_insert_with(CellProps::new)
283            .readonly = prop;
284        self.maxk = Some(self.maxk.map_or(pos, |max| max.max(pos)));
285    }
286
287    #[inline]
288    pub fn set_cell_val(&mut self, pos: usize, val: Val) {
289        if let Some(cell) = self.hm.get_mut(&pos) {
290            cell.val = val;
291        } else {
292            self.hm.insert(pos, TableCell { val, props: None });
293        }
294        self.maxk = Some(self.maxk.map_or(pos, |max| max.max(pos)));
295    }
296
297    #[inline]
298    pub fn set_cell(&mut self, pos: usize, cell: TableCell) {
299        self.hm.insert(pos, cell);
300        self.maxk = Some(self.maxk.map_or(pos, |max| max.max(pos)));
301    }
302}