1use alloc::string::ToString;
2use alloc::{rc::Rc, string::String, vec, vec::Vec};
3use core::cell::RefCell;
4use hashbrown::HashSet;
5
6use crate::args::{InsertArgs, InsertRow};
7use crate::utils::consecutive_ranges::consecutive_ranges_owned;
8use crate::utils::utils_fns::binary_search_ins_pos;
9use crate::{CellProps, Change, EventData, IndexCell, NO_END, Table, Val, str_err};
10
11impl Table {
12 pub fn insert(
16 &mut self,
17 kwargs: Option<InsertArgs>,
18 ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
19 let kwargs = kwargs.unwrap_or_default();
20 let rows = kwargs.rows.unwrap_or(vec![InsertRow {
21 iid: None,
22 val: None,
23 vals: None,
24 open: false,
25 dim: None,
26 }]);
27
28 if rows.is_empty() {
29 return Ok(None);
30 }
31 let empty_val: Val = self.opts.empty_val.clone();
32 let empty_index_val: Val = self.opts.empty_index_val.clone();
33 let tree_mode = self.opts.tree_mode;
34
35 let mut event_data: EventData = self.cr_new_event(false);
36 let mut new_iids: HashSet<Rc<str>> = HashSet::new();
37 let dim = self.cr_get_default_row_dim();
38 let ncols = Self::acr_total_cols(&self.grid.header.cells);
39 let par = kwargs.par.unwrap_or_default();
41
42 let pos = match kwargs.pos {
43 Some(pos) => Some(pos as usize),
44 None => None,
45 };
46 let start_rn = self.cr_tree_get_iid_insert_row(pos, &par)?;
48
49 let opt_inherit_row = self.cr_get_inherit_row(
51 &self.grid.index.iid_to_row,
52 start_rn,
53 kwargs.inherit.as_str(),
54 )?;
55 let do_inherit = opt_inherit_row.is_some();
56 let inherit_row = opt_inherit_row.unwrap_or(0);
57
58 let chn_splice_pos: Option<usize> = if !par.is_empty() {
59 let chn =
60 Self::acr_tree_iid_chn(&self.grid.index.cells, &self.grid.index.iid_to_row, &par)?;
61 let pos = binary_search_ins_pos(&chn, &self.grid.index.iid_to_row, start_rn)?;
62 Some(pos)
63 } else {
64 None
65 };
66 let mut chn_to_splice: Vec<Rc<str>> = Vec::with_capacity(rows.len());
69 let sorted_seq: Vec<usize> = (start_rn..start_rn + rows.len()).collect();
70
71 self.grid.push_rows(&sorted_seq);
73 self.grid.index.add_rows_just_push_hm(&sorted_seq);
74
75 let (vis, par_rc) = match (|| -> Result<(bool, Rc<str>), String> {
77 if tree_mode {
78 if par.is_empty() {
79 Ok((true, self.grid.index.empty_par.clone()))
80 } else {
81 let par_row = Self::acr_pos(&self.grid.index.iid_to_row, par.as_str())?;
82 let par_cell = Self::acr_icell(&self.grid.index.cells, par_row)?;
83 Ok((par_cell.vis && par_cell.open, par_cell.iid.clone()))
84 }
85 } else {
86 Ok((true, self.grid.index.empty_par.clone()))
87 }
88 })() {
89 Ok(tup) => tup,
90 Err(e) => {
91 self.grid.pull_rows(&sorted_seq);
93 self.grid.index.del_rows_just_pull_hm(&sorted_seq);
94 return Err(e);
95 }
96 };
97
98 let mut rn = start_rn;
99
100 let build_result = (|| -> Result<(), String> {
102 for (i, row_spec) in rows.into_iter().enumerate() {
103 rn = start_rn + i;
105
106 let iid: Rc<str> = if let Some(iid) = row_spec.iid {
108 if self.grid.index.iid_to_row.contains_key(iid.as_str()) {
110 return Err(str_err!("iid already exists: {}", iid));
111 }
112 Rc::from(iid)
113 } else {
114 Rc::from(self.grid.index.new_iid()?)
115 };
116 if !new_iids.insert(iid.clone()) {
118 return Err(str_err!("Repeated iid in rows: {}", iid));
119 };
120
121 let val = if let Some(val) = row_spec.val {
124 val
125 } else if tree_mode {
126 Val::Str(iid.to_string())
127 } else {
128 empty_index_val.clone()
129 };
130 let index_props: Option<CellProps> = if do_inherit {
131 self.grid.index.clone_props(&inherit_row)
132 } else {
133 None
134 };
135
136 let new_icell = IndexCell {
138 iid: iid.clone(),
139 val,
140 vals: Self::build_row_cells(
141 &self.grid.index.cells,
142 &self.grid.header,
143 row_spec.vals,
144 inherit_row,
145 do_inherit,
146 &empty_val,
147 ncols,
148 )?,
149 dim: row_spec.dim.unwrap_or(dim),
150 vis,
151 par: par_rc.clone(),
152 chn: Vec::new(),
153 open: row_spec.open,
154 props: index_props,
155 };
156
157 chn_to_splice.push(iid.clone());
159
160 self.grid.index.add_row(rn, iid, new_icell);
162 }
163
164 if let Some(chn_splice_pos) = chn_splice_pos {
166 let chn = Self::acr_tree_iid_chn_mut(
167 &mut self.grid.index.cells,
168 &self.grid.index.iid_to_row,
169 &par,
170 )?;
171 chn.splice(
172 chn_splice_pos..chn_splice_pos,
173 core::mem::take(&mut chn_to_splice),
174 );
175 }
176 Ok(())
177 })();
178
179 match build_result {
180 Ok(_) => {}
181 Err(e) => {
182 for iid in chn_to_splice.iter() {
184 self.grid.index.iid_to_row.remove(iid);
185 }
186 let added_count = chn_to_splice.len();
187 if added_count > 0 {
188 self.grid
189 .index
190 .cells
191 .drain(start_rn..start_rn + added_count);
192 }
193 self.grid.pull_rows(&sorted_seq);
194 self.grid.index.del_rows_just_pull_hm(&sorted_seq);
195 return Err(e);
196 }
197 };
198
199 let num_visible_added = if vis { sorted_seq.len() } else { 0 };
201 let disp_insert_pos = Self::acr_compute_disp_insert_pos(&self.grid.disp_rows, start_rn);
202
203 Self::acr_remake_rows(
205 &mut self.grid.canvas_rows,
206 &mut self.grid.disp_rows,
207 &self.grid.index.cells,
208 self.opts.horizontal_grid_line_width.clone(),
209 );
210 self.acr_adjust_selections_after_row_insert(disp_insert_pos, num_visible_added);
211
212 if kwargs.select {
214 Self::acr_deselect_all(
215 &mut self.sel,
216 if kwargs.save_selection {
217 Some(&mut event_data)
218 } else {
219 None
220 },
221 );
222 for (start, end) in consecutive_ranges_owned(
223 sorted_seq
224 .iter()
225 .filter_map(|n| Self::acr_data_to_disp_opt(&self.grid.disp_rows, *n)),
226 ) {
227 Self::acr_add_selection_box(&mut self.sel, &self.grid, start, end, 0, NO_END, true);
228 }
229 if kwargs.save_selection {
230 event_data.changes.push(Change::add_selection_boxes(
231 self.sel.selection_boxes.len(),
232 None,
233 ));
234 }
235 }
236
237 event_data.changes.push(Change::AddRows(sorted_seq));
239 self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
240 }
241}