1use alloc::format;
2use alloc::rc::Rc;
3use alloc::string::String;
4use alloc::vec;
5use alloc::vec::Vec;
6use core::cell::RefCell;
7use hashbrown::HashMap;
8
9use crate::args::{CycleHandling, DuplicateIdHandling, EmptyIdHandling, TreeExtendArgs};
10use crate::str_err;
11use crate::types::extensions::TrySetExt;
12use crate::utils::consecutive_ranges::consecutive_ranges_owned;
13use crate::{Change, EventData, Header, IndexCell, MaxMap, NO_END, Table, TableCell, Val};
14
15#[inline]
16fn tree_extend_get_descendants<'a>(
17 tree: &'a HashMap<Rc<str>, IndexCell>,
18 initial_chn: &[Rc<str>],
19) -> impl Iterator<Item = Rc<str>> + 'a {
20 struct TreeDescendantIterator<'a> {
21 tree: &'a HashMap<Rc<str>, IndexCell>,
22 stack: Vec<Rc<str>>,
23 }
24
25 impl Iterator for TreeDescendantIterator<'_> {
26 type Item = Rc<str>;
27
28 fn next(&mut self) -> Option<Self::Item> {
29 self.stack.pop().map(|current| {
30 if let Some(cell) = self.tree.get(¤t) {
31 for child in cell.chn.iter().rev().cloned() {
32 self.stack.push(child);
33 }
34 }
35 current
36 })
37 }
38 }
39
40 let stack = initial_chn.iter().cloned().rev().collect::<Vec<_>>();
41 TreeDescendantIterator { tree, stack }
42}
43
44#[inline]
45fn tree_extend_check_inf_loop(
46 tree_map: &HashMap<Rc<str>, IndexCell>,
47 initial_chn: &[Rc<str>],
48 par: &str,
49) -> bool {
50 tree_extend_get_descendants(tree_map, initial_chn).any(|did| &*did == par)
51}
52
53impl Table {
54 #[inline]
56 pub(crate) fn build_row_cells(
57 icells: &[IndexCell],
58 header: &Header,
59 vals: Option<Vec<(String, Val)>>,
60 inherit_row: usize,
61 do_inherit: bool,
62 empty_val: &Val,
63 ncols: usize,
64 ) -> Result<MaxMap<TableCell>, String> {
65 let mut cols_map: MaxMap<TableCell> = MaxMap::new();
66 if do_inherit {
67 let mut provided: Vec<Option<Val>> = vec![None; ncols];
68 if let Some(vals) = vals {
69 for (key, val) in vals.into_iter() {
70 let cn = Self::acr_pos(&header.iid_to_col, &key)?;
71 provided.try_set(cn, Some(val))?;
73 }
74 }
75 for (cn, opt_val) in provided.into_iter().enumerate() {
76 let props = Self::acr_tcell_props(icells, inherit_row, cn).cloned();
77 if let Some(val) = opt_val {
78 cols_map.set_cell(cn, TableCell { val, props });
80 } else if props.is_some() {
81 cols_map.set_cell(
83 cn,
84 TableCell {
85 val: empty_val.clone(),
86 props,
87 },
88 );
89 }
90 }
92 } else {
93 if let Some(vals) = vals {
95 for (key, val) in vals.into_iter() {
96 let cn = Self::acr_pos(&header.iid_to_col, &key)?;
97 cols_map.set_cell(cn, TableCell { val, props: None });
98 }
99 }
100 }
101 Ok(cols_map)
102 }
103
104 pub fn tree_extend(
106 &mut self,
107 kwargs: Option<TreeExtendArgs>,
108 ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
109 let kwargs = kwargs.unwrap_or_default();
110 let empty_id_handling = kwargs.empty_ids;
111 let duplicate_id_handling = kwargs.duplicate_ids;
112 let cycle_handling = kwargs.cycles;
113 let check_for_cycles: bool = cycle_handling != CycleHandling::Ignore;
114 let mut tree_map: HashMap<Rc<str>, IndexCell> = HashMap::with_capacity(kwargs.rows.len());
115 let mut tops: Vec<Rc<str>> = Vec::with_capacity(kwargs.rows.len() / 2);
116 let mut par_stubs: HashMap<Rc<str>, Vec<Rc<str>>> = HashMap::new();
118 let empty_val: Val = self.opts.empty_val.clone();
119 let empty_ival: Val = self.opts.empty_index_val.clone();
120 let default_dim = self.cr_get_default_row_dim();
121 let mut event_data: EventData = self.cr_new_event(false);
122 let ncols = Self::acr_total_cols(&self.grid.header.cells);
123 let mut row_ctr = Self::acr_total_rows(&self.grid.index.cells);
124
125 let opt_inherit_row =
127 self.cr_get_inherit_row(&self.grid.index.iid_to_row, row_ctr, &kwargs.inherit)?;
128 let do_inherit = opt_inherit_row.is_some();
129 let inherit_row = opt_inherit_row.unwrap_or(0);
130 let index_props = if do_inherit {
131 self.grid.index.clone_props(&inherit_row)
132 } else {
133 None
134 };
135
136 for mut row_spec in kwargs.rows.into_iter() {
138 let iid: Rc<str> = if row_spec.iid.is_empty() {
140 match empty_id_handling {
141 EmptyIdHandling::Error => {
142 return Err(str_err!(
143 "Empty iid. Parent: {:?}, Text: {:?}, Values: {:?}",
144 row_spec.par,
145 row_spec.val,
146 row_spec.vals
147 ));
148 }
149 EmptyIdHandling::Ignore => {
150 continue;
151 }
152 EmptyIdHandling::New => {
153 let mut new = self.grid.index.new_iid()?;
155 while tree_map.contains_key(new.as_str()) {
156 new = self.grid.index.new_iid()?;
157 }
158 Rc::from(new)
159 }
160 }
161 } else if self
163 .grid
164 .index
165 .iid_to_row
166 .contains_key(row_spec.iid.as_str())
167 {
168 match duplicate_id_handling {
169 DuplicateIdHandling::Error => {
170 return Err(str_err!("iid already exists: {}", row_spec.iid));
171 }
172 DuplicateIdHandling::Rename => {
173 let mut n: u64 = 1;
174 let iid = row_spec.iid.as_str();
175 let mut new = format!("{iid}_{n}");
176 while self.grid.index.iid_to_row.contains_key(new.as_str()) {
177 n += 1;
178 new = format!("{iid}_{n}");
179 }
180 Rc::from(new)
181 }
182 }
183 } else {
184 Rc::from(row_spec.iid)
185 };
186
187 let mut par: Rc<str> = Rc::from(row_spec.par);
188 if self.grid.index.iid_to_row.contains_key(&par) {
190 match duplicate_id_handling {
191 DuplicateIdHandling::Error => {
192 return Err(str_err!("parent already exists: {}", par));
193 }
194 DuplicateIdHandling::Rename => {
195 let mut n: u64 = 1;
196 let mut new = format!("{par}_{n}");
197 while self.grid.index.iid_to_row.contains_key(new.as_str()) {
198 n += 1;
199 new = format!("{par}_{n}");
200 }
201 par = Rc::from(new);
202 }
203 }
204 }
205
206 let iid = if tree_map.contains_key(&iid) {
208 match duplicate_id_handling {
209 DuplicateIdHandling::Error => {
210 return Err(str_err!("iid is a duplicate in rows: {}", iid));
211 }
212 DuplicateIdHandling::Rename => {
213 let mut n: u64 = 1;
214 let mut new = format!("{iid}_{n}");
215 while tree_map.contains_key(new.as_str())
217 || self.grid.index.iid_to_row.contains_key(new.as_str())
218 {
219 n += 1;
220 new = format!("{iid}_{n}");
221 }
222 Rc::from(new)
223 }
224 }
225 } else {
226 iid
227 };
228
229 let mut new_icell = IndexCell {
230 iid: iid.clone(),
231 val: row_spec.val.unwrap_or(empty_ival.clone()),
232 vals: Self::build_row_cells(
233 &self.grid.index.cells,
234 &self.grid.header,
235 row_spec.vals.take(),
236 inherit_row,
237 do_inherit,
238 &empty_val,
239 ncols,
240 )?,
241 dim: row_spec.dim.unwrap_or(default_dim),
242 vis: false,
243 par: self.grid.index.empty_par.clone(),
244 chn: Vec::new(),
245 open: row_spec.open,
246 props: index_props.clone(),
247 };
248
249 if let Some(pending_chn) = par_stubs.remove(&iid) {
253 new_icell.chn = pending_chn;
254 }
255
256 if iid == par {
258 match cycle_handling {
259 CycleHandling::Error => {
260 return Err(str_err!("iid: {iid} equal to parent"));
261 }
262 CycleHandling::Skip => {
263 continue;
264 }
265 CycleHandling::OnlyPrior => {
266 break;
267 }
268 _ => par = self.grid.index.empty_par.clone(),
269 }
270 }
271 if check_for_cycles {
272 let inf_loop =
273 tree_extend_check_inf_loop(&tree_map, new_icell.chn.as_slice(), &par);
274 if inf_loop {
275 match cycle_handling {
276 CycleHandling::Error => {
277 return Err(str_err!(
278 "Cycle detected for iid: {} with parent: {}",
279 iid,
280 par
281 ));
282 }
283 CycleHandling::Skip => {
284 continue;
285 }
286 CycleHandling::Clear => {
287 par = self.grid.index.empty_par.clone();
288 }
289 CycleHandling::OnlyPrior => {
290 break;
291 }
292 CycleHandling::Ignore => unreachable!(),
293 }
294 }
295 }
296
297 if !par.is_empty() {
299 if let Some(par_cell) = tree_map.get_mut(&par) {
300 new_icell.par = par;
304 par_cell.chn.push(iid.clone());
305 } else {
306 par_stubs
311 .entry(par)
312 .or_insert_with(Vec::new)
313 .push(iid.clone());
314 }
315 } else {
316 new_icell.vis = true;
317 tops.push(iid.clone());
318 }
319 tree_map.insert(iid, new_icell);
320 }
321
322 for (iid, chn) in par_stubs.into_iter() {
324 let cols_map = Self::build_row_cells(
325 &self.grid.index.cells,
326 &self.grid.header,
327 None,
328 inherit_row,
329 do_inherit,
330 &empty_val,
331 ncols,
332 )?;
333 let stub = IndexCell {
334 iid: iid.clone(),
335 val: empty_ival.clone(),
336 vals: cols_map,
337 dim: default_dim,
338 vis: true,
339 par: self.grid.index.empty_par.clone(),
340 chn,
341 open: false,
342 props: index_props.clone(),
343 };
344 tops.push(iid.clone());
346 tree_map.insert(iid, stub);
347 }
348
349 if tree_map.is_empty() {
351 return Err(str_err!("No rows to be added"));
352 }
353
354 let orig_disp_len = self.grid.disp_rows.len();
355 let orig_canvas_len = self.grid.canvas_rows.len();
356 let orig_index_cells_len = self.grid.index.cells.len();
357 let mut sorted_seq: Vec<usize> = Vec::with_capacity(tree_map.len());
360
361 let mut acc: u64 = self.grid.canvas_rows.last().cloned().unwrap_or(0);
363 let mut stack: Vec<(Rc<str>, bool, Rc<str>)> = Vec::with_capacity(100);
364 self.grid.index.cells.reserve(tree_map.len());
365 self.grid.index.iid_to_row.reserve(tree_map.len());
366
367 let mut_result: Result<(), String> = (|| -> Result<(), String> {
368 for top in tops.into_iter() {
369 sorted_seq.push(row_ctr);
370 let icell = tree_map
371 .remove(&top)
372 .ok_or_else(|| str_err!("IndexCell: {} not found in tree_map", top))?;
373 let child_vis = icell.open;
374 for child in icell.chn.iter().rev().cloned() {
375 stack.push((child, child_vis, top.clone()));
376 }
377 self.grid.disp_rows.push(row_ctr);
378 acc += icell.dim;
379 self.grid.canvas_rows.push(acc);
380 self.grid.index.push_row(row_ctr, icell.iid.clone(), icell);
381 row_ctr += 1;
382
383 while let Some((not_top, inherited_vis, par_iid)) = stack.pop() {
384 sorted_seq.push(row_ctr);
385 let mut icell = tree_map
386 .remove(¬_top)
387 .ok_or_else(|| str_err!("IndexCell: {} not found in tree_map", not_top))?;
388 icell.par = par_iid;
389 icell.vis = inherited_vis;
390 let child_vis = inherited_vis && icell.open;
391 for child in icell.chn.iter().rev().cloned() {
392 stack.push((child, child_vis, not_top.clone()));
393 }
394 if inherited_vis {
396 self.grid.disp_rows.push(row_ctr);
397 acc += icell.dim;
398 self.grid.canvas_rows.push(acc);
399 }
400 self.grid.index.push_row(row_ctr, icell.iid.clone(), icell);
402 row_ctr += 1;
403 }
404 }
405 Ok(())
406 })();
407
408 if let Err(e) = mut_result {
409 self.grid.disp_rows.truncate(orig_disp_len);
410 self.grid.canvas_rows.truncate(orig_canvas_len);
411 for cell in &self.grid.index.cells[orig_index_cells_len..] {
412 self.grid.index.iid_to_row.remove(&cell.iid);
413 }
414 self.grid.index.cells.truncate(orig_index_cells_len);
415 return Err(e);
416 }
417
418 if kwargs.select {
420 Self::acr_deselect_all(
421 &mut self.sel,
422 if kwargs.save_selection {
423 Some(&mut event_data)
424 } else {
425 None
426 },
427 );
428 for (start, end) in consecutive_ranges_owned(
429 sorted_seq
430 .iter()
431 .filter_map(|n| Self::acr_data_to_disp_opt(&self.grid.disp_rows, *n)),
432 ) {
433 Self::acr_add_selection_box(&mut self.sel, &self.grid, start, end, 0, NO_END, true);
434 }
435 if kwargs.save_selection {
436 event_data.changes.push(Change::add_selection_boxes(
437 self.sel.selection_boxes.len(),
438 None,
439 ));
440 }
441 }
442
443 event_data.changes.push(Change::AddRows(sorted_seq));
444 self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
445 }
446}