umya_spreadsheet/helper/
range.rs

1use crate::helper::coordinate::*;
2
3use super::coordinate;
4
5/// `(col, row)`
6pub type BasicCellIndex = (u32, u32);
7
8/// # Returns
9/// `Vec<(col, row)>`
10pub fn get_coordinate_list(range_str: &str) -> Vec<BasicCellIndex> {
11    let (row_start, row_end, col_start, col_end) = get_start_and_end_point(range_str);
12
13    (row_start..=row_end)
14        .flat_map(|row_num| (col_start..=col_end).map(move |col_num| (col_num, row_num)))
15        .collect()
16}
17
18pub fn get_start_and_end_point(range_str: &str) -> (u32, u32, u32, u32) {
19    let upper_rng_str = range_str.to_uppercase();
20    let coordinate_collection: Vec<&str> = upper_rng_str.split(':').collect();
21
22    assert!(
23        matches!(coordinate_collection.len(), 1 | 2),
24        "Non-standard range."
25    );
26
27    let mut is_col_select = false;
28    let mut is_row_select = false;
29    let (mut col_start, mut col_end, mut row_start, mut row_end) = (0, 0, 0, 0);
30
31    let (col, row, ..) = index_from_coordinate(coordinate_collection[0]);
32
33    if let Some(v) = col {
34        is_col_select = true;
35        col_start = v;
36        col_end = v;
37    }
38
39    if let Some(v) = row {
40        is_row_select = true;
41        row_start = v;
42        row_end = v;
43    }
44
45    if coordinate_collection.len() == 2 {
46        let (col, row, ..) = index_from_coordinate(coordinate_collection[1]);
47
48        match col {
49            Some(v) => {
50                col_end = v;
51            }
52            None => {
53                assert!(is_col_select, "Non-standard range.");
54            }
55        };
56
57        match row {
58            Some(v) => {
59                row_end = v;
60            }
61            None => {
62                assert!(is_row_select, "Non-standard range.");
63            }
64        }
65    }
66
67    (row_start, row_end, col_start, col_end)
68}
69
70#[inline]
71pub fn get_split_range(range: &str) -> Vec<&str> {
72    range.split(':').collect()
73}
74
75#[inline]
76pub fn get_join_range(coordinate_list: &[String]) -> String {
77    coordinate_list.join(":")
78}