tree_table/api/
sort_rows_by_col.rs1use alloc::{rc::Rc, string::String, vec::Vec};
2use core::{cell::RefCell, cmp::Ordering};
3use hashbrown::{HashMap, HashSet};
4
5use crate::args::SortRowsArgs;
6use crate::{EventData, Table, Val};
7
8impl Table {
9 pub fn sort_rows_by_cols(
10 &mut self,
11 kwargs: Option<SortRowsArgs>,
12 ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
13 let num_rows = Self::acr_total_rows(&self.grid.index.cells) as u64;
14 if num_rows == 0 {
15 return Ok(None);
16 }
17
18 let kwargs: SortRowsArgs = kwargs.unwrap_or_default();
19 if kwargs.keys.is_empty() {
20 return Ok(None);
21 }
22
23 let span = self.cr_key_to_span(kwargs.span)?;
24 let rows: Vec<usize> = span.rows(&self.grid).collect();
25
26 if rows.len() <= 1 {
27 return Ok(None);
28 }
29
30 let compare_fn: fn(&Val, &Val) -> Ordering = kwargs.sort_key.get_cmp();
31 let mut indices: Vec<usize> = rows.clone();
32
33 indices.sort_by(|&a, &b| {
34 for &(col_u64, ascending) in &kwargs.keys {
35 let col = col_u64 as usize;
36 let va =
37 Self::acr_tcell_val(&self.grid.index.cells, a, col).unwrap_or(&Val::Nil(()));
38 let vb =
39 Self::acr_tcell_val(&self.grid.index.cells, b, col).unwrap_or(&Val::Nil(()));
40
41 let mut cmp = compare_fn(va, vb);
42 if cmp != Ordering::Equal {
43 if !ascending {
44 cmp = cmp.reverse();
45 }
46 return cmp;
47 }
48 }
49 Ordering::Equal });
51
52 if indices == rows {
53 return Ok(None);
54 }
55
56 let mut old_to_new: Vec<(usize, usize)> = Vec::new();
57 let mut new_to_old: HashMap<usize, usize> = HashMap::new();
58 let mut seen_old: HashSet<usize> = HashSet::new();
59 for (new_pos, &old) in indices.iter().enumerate() {
60 let new = rows[new_pos];
61 if old == new {
62 continue;
63 }
64 seen_old.insert(old);
65 old_to_new.push((old, new));
66 new_to_old.insert(new, old);
67 }
68
69 if old_to_new.is_empty() {
70 return Ok(None);
71 }
72
73 let mut event_data = self.cr_new_event(kwargs.save_selection);
74
75 if let Err(e) = self.cr_move_rows(
76 &mut event_data,
77 seen_old,
78 old_to_new,
79 new_to_old,
80 None,
81 true,
82 ) {
83 self.cr_roll_back(Rc::new(RefCell::new(event_data)));
84 return Err(e);
85 }
86
87 if kwargs.select {
88 Self::acr_deselect_all(&mut self.sel, None);
89 let mut moved: Vec<usize> = self.extract_disp_moved_rows(&event_data);
90 if !moved.is_empty() {
91 moved.sort_unstable();
92 self.cr_select_rows_from(moved);
93 }
94 }
95
96 self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
97 }
98}