sheets_diff/core/
utils.rs1pub fn filter_same_name_sheets(old_sheets: &[String], new_sheets: &[String]) -> Vec<String> {
3 old_sheets
4 .iter()
5 .filter(|s| new_sheets.contains(s))
6 .cloned()
7 .collect()
8}
9
10pub fn diff_range(
14 old_start: Option<(u32, u32)>,
15 new_start: Option<(u32, u32)>,
16 old_end: Option<(u32, u32)>,
17 new_end: Option<(u32, u32)>,
18) -> (u32, u32, u32, u32) {
19 let (old_start_row, old_start_col) = old_start.unwrap_or((u32::MAX, u32::MAX));
20 let (new_start_row, new_start_col) = new_start.unwrap_or((u32::MAX, u32::MAX));
21 let (old_end_row, old_end_col) = old_end.unwrap_or((u32::MIN, u32::MIN));
22 let (new_end_row, new_end_col) = new_end.unwrap_or((u32::MIN, u32::MIN));
23
24 let start_row = old_start_row.min(new_start_row);
25 let start_col = old_start_col.min(new_start_col);
26 let end_row = old_end_row.max(new_end_row);
27 let end_col = old_end_col.max(new_end_col);
28
29 (start_row, start_col, end_row + 1, end_col + 1)
30}
31
32pub fn col_to_label(mut col: usize) -> String {
42 assert!(col > 0, "Excel column index is 1-based; col == 0 is invalid");
43
44 let mut bytes = Vec::new();
45 while col > 0 {
46 let rem = (col - 1) % 26;
47 bytes.push(b'A' + rem as u8);
48 col = (col - 1) / 26;
49 }
50 bytes.reverse();
51 String::from_utf8(bytes).expect("only ASCII uppercase letters are generated")
53}
54
55pub fn cell_pos_to_address(row: usize, col: usize) -> String {
59 format!("{}{}", col_to_label(col), row)
60}