excel_cli/utils/
cell_navigation.rs1use crate::excel::Sheet;
2
3#[derive(Debug, Clone, Copy)]
5pub enum Direction {
6 Left,
7 Right,
8 Up,
9 Down,
10}
11
12pub fn find_non_empty_cell(
16 sheet: &Sheet,
17 current_pos: (usize, usize),
18 direction: Direction,
19 max_bounds: (usize, usize),
20) -> Option<(usize, usize)> {
21 let (row, col) = current_pos;
22 let (max_row, max_col) = max_bounds;
23
24 match direction {
26 Direction::Left if col <= 1 => return None,
27 Direction::Right if col >= max_col => return None,
28 Direction::Up if row <= 1 => return None,
29 Direction::Down if row >= max_row => return None,
30 _ => {}
31 }
32
33 let current_cell_is_empty = row >= sheet.data.len()
35 || col >= sheet.data[row].len()
36 || sheet.data[row][col].value.is_empty();
37
38 if current_cell_is_empty {
39 match direction {
41 Direction::Left => {
42 for c in (1..col).rev() {
43 if row < sheet.data.len()
44 && c < sheet.data[row].len()
45 && !sheet.data[row][c].value.is_empty()
46 {
47 return Some((row, c));
48 }
49 }
50 Some((row, 1))
52 }
53 Direction::Right => {
54 for c in (col + 1)..=max_col {
55 if row < sheet.data.len()
56 && c < sheet.data[row].len()
57 && !sheet.data[row][c].value.is_empty()
58 {
59 return Some((row, c));
60 }
61 }
62 Some((row, max_col))
64 }
65 Direction::Up => {
66 for r in (1..row).rev() {
67 if r < sheet.data.len()
68 && col < sheet.data[r].len()
69 && !sheet.data[r][col].value.is_empty()
70 {
71 return Some((r, col));
72 }
73 }
74 Some((1, col))
76 }
77 Direction::Down => {
78 for r in (row + 1)..=max_row {
79 if r < sheet.data.len()
80 && col < sheet.data[r].len()
81 && !sheet.data[r][col].value.is_empty()
82 {
83 return Some((r, col));
84 }
85 }
86 Some((max_row, col))
88 }
89 }
90 } else {
91 match direction {
93 Direction::Left => {
94 let mut last_non_empty = col;
95
96 for c in (1..col).rev() {
97 if row < sheet.data.len() && c < sheet.data[row].len() {
98 if sheet.data[row][c].value.is_empty() {
99 return Some((row, c + 1));
100 } else {
101 last_non_empty = c;
102 }
103 } else {
104 return Some((row, c + 1));
105 }
106 }
107
108 Some((row, last_non_empty))
109 }
110 Direction::Right => {
111 let mut last_non_empty = col;
112
113 for c in (col + 1)..=max_col {
114 if row < sheet.data.len() && c < sheet.data[row].len() {
115 if sheet.data[row][c].value.is_empty() {
116 return Some((row, c - 1));
117 } else {
118 last_non_empty = c;
119 }
120 } else {
121 return Some((row, c - 1));
122 }
123 }
124
125 Some((row, last_non_empty))
126 }
127 Direction::Up => {
128 let mut last_non_empty = row;
129
130 for r in (1..row).rev() {
131 if r < sheet.data.len() && col < sheet.data[r].len() {
132 if sheet.data[r][col].value.is_empty() {
133 return Some((r + 1, col));
134 } else {
135 last_non_empty = r;
136 }
137 } else {
138 return Some((r + 1, col));
139 }
140 }
141
142 Some((last_non_empty, col))
143 }
144 Direction::Down => {
145 let mut last_non_empty = row;
146
147 for r in (row + 1)..=max_row {
148 if r < sheet.data.len() && col < sheet.data[r].len() {
149 if sheet.data[r][col].value.is_empty() {
150 return Some((r - 1, col));
151 } else {
152 last_non_empty = r;
153 }
154 } else {
155 return Some((r - 1, col));
156 }
157 }
158
159 Some((last_non_empty, col))
160 }
161 }
162 }
163}