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}