logisheets_controller/range_manager/executors/
mod.rs1mod delete_block_line;
2mod delete_line;
3mod input;
4mod insert_block_line;
5mod insert_line;
6mod occupy_addr_range;
7mod remove_block;
8mod utils;
9use std::collections::HashSet;
10
11use delete_block_line::delete_block_line;
12use delete_line::delete_line;
13use input::input;
14use insert_block_line::insert_block_line;
15use insert_line::insert_line;
16use logisheets_base::{errors::BasicError, BlockRange, NormalRange, Range, RangeId, SheetId};
17use remove_block::remove_block;
18
19use crate::{
20 edit_action::EditPayload, range_manager::executors::occupy_addr_range::occupy_addr_range, Error,
21};
22
23use super::{ctx::RangeExecCtx, manager::RangeManager};
24
25pub struct RangeExecutor {
26 pub manager: RangeManager,
27 pub dirty_ranges: HashSet<(SheetId, RangeId)>,
28 pub removed_ranges: HashSet<(SheetId, RangeId)>,
29}
30
31impl RangeExecutor {
32 pub fn new(manager: RangeManager) -> Self {
33 Self {
34 manager,
35 dirty_ranges: HashSet::new(),
36 removed_ranges: HashSet::new(),
37 }
38 }
39
40 pub fn execute<C: RangeExecCtx>(self, ctx: &C, payload: EditPayload) -> Result<Self, Error> {
41 match payload {
42 EditPayload::MoveBlock(move_block) => {
43 let sheet_id = ctx
44 .fetch_sheet_id_by_index(move_block.sheet_idx)
45 .map_err(|l| BasicError::SheetIdxExceed(l))?;
46 let (row_cnt, col_cnt) = ctx.get_block_size(sheet_id, move_block.id).unwrap();
47 if ctx.any_other_blocks_in(
48 sheet_id,
49 move_block.id,
50 move_block.new_master_row,
51 move_block.new_master_col,
52 row_cnt + move_block.new_master_row - 1,
53 col_cnt + move_block.new_master_col - 1,
54 ) {
55 Ok(self)
56 } else {
57 let start = ctx
58 .fetch_norm_cell_id(
59 &sheet_id,
60 move_block.new_master_row,
61 move_block.new_master_col,
62 )
63 .unwrap();
64 let end = ctx
65 .fetch_norm_cell_id(
66 &sheet_id,
67 move_block.new_master_row + row_cnt - 1,
68 move_block.new_master_col + col_cnt - 1,
69 )
70 .unwrap();
71 let res = occupy_addr_range(self, sheet_id, start, end, ctx);
72 Ok(res)
73 }
74 }
75 EditPayload::RemoveBlock(p) => {
76 let sheet_id = ctx
77 .fetch_sheet_id_by_index(p.sheet_idx)
78 .map_err(|l| BasicError::SheetIdxExceed(l))?;
79 let res = remove_block(self, sheet_id, p.id);
80 Ok(res)
81 }
82 EditPayload::CreateBlock(create_block) => {
83 let sheet_id = ctx
84 .fetch_sheet_id_by_index(create_block.sheet_idx)
85 .map_err(|l| BasicError::SheetIdxExceed(l))?;
86 let start = ctx.fetch_norm_cell_id(
87 &sheet_id,
88 create_block.master_row,
89 create_block.master_col,
90 )?;
91 let end = ctx.fetch_norm_cell_id(
92 &sheet_id,
93 create_block.master_row + create_block.row_cnt - 1,
94 create_block.master_col + create_block.col_cnt - 1,
95 )?;
96 let result = occupy_addr_range(self, sheet_id, start, end, ctx);
97 Ok(result)
98 }
99 EditPayload::CellInput(p) => {
100 let sheet_id = ctx
101 .fetch_sheet_id_by_index(p.sheet_idx)
102 .map_err(|l| BasicError::SheetIdxExceed(l))?;
103 let res = input(self, sheet_id, p.row, p.col, ctx)?;
104 Ok(res)
105 }
106 EditPayload::CellClear(p) => {
107 let sheet_id = ctx
108 .fetch_sheet_id_by_index(p.sheet_idx)
109 .map_err(|l| BasicError::SheetIdxExceed(l))?;
110 let res = input(self, sheet_id, p.row, p.col, ctx)?;
111 Ok(res)
112 }
113 EditPayload::DeleteSheet(_) => todo!(),
114 EditPayload::InsertCols(insert_cols) => {
115 let sheet_id = ctx
116 .fetch_sheet_id_by_index(insert_cols.sheet_idx)
117 .map_err(|l| BasicError::SheetIdxExceed(l))?;
118 let result = insert_line(
119 self,
120 sheet_id,
121 false,
122 insert_cols.start,
123 insert_cols.count as u32,
124 ctx,
125 );
126 Ok(result)
127 }
128 EditPayload::DeleteCols(delete_cols) => {
129 let sheet_id = ctx
130 .fetch_sheet_id_by_index(delete_cols.sheet_idx)
131 .map_err(|l| BasicError::SheetIdxExceed(l))?;
132 let result = delete_line(
133 self,
134 sheet_id,
135 false,
136 delete_cols.start,
137 delete_cols.count as u32,
138 ctx,
139 );
140 Ok(result)
141 }
142 EditPayload::InsertRows(insert_rows) => {
143 let sheet_id = ctx
144 .fetch_sheet_id_by_index(insert_rows.sheet_idx)
145 .map_err(|l| BasicError::SheetIdxExceed(l))?;
146 let result = insert_line(
147 self,
148 sheet_id,
149 true,
150 insert_rows.start,
151 insert_rows.count as u32,
152 ctx,
153 );
154 Ok(result)
155 }
156 EditPayload::DeleteRows(delete_rows) => {
157 let sheet_id = ctx
158 .fetch_sheet_id_by_index(delete_rows.sheet_idx)
159 .map_err(|l| BasicError::SheetIdxExceed(l))?;
160 let result = delete_line(
161 self,
162 sheet_id,
163 true,
164 delete_rows.start,
165 delete_rows.count as u32,
166 ctx,
167 );
168 Ok(result)
169 }
170 EditPayload::InsertColsInBlock(p) => {
171 let sheet_id = ctx
172 .fetch_sheet_id_by_index(p.sheet_idx)
173 .map_err(|l| BasicError::SheetIdxExceed(l))?;
174 let res = insert_block_line(
175 self,
176 sheet_id,
177 p.block_id,
178 false,
179 p.start as u32,
180 p.cnt as u32,
181 ctx,
182 );
183 Ok(res)
184 }
185 EditPayload::DeleteColsInBlock(p) => {
186 let sheet_id = ctx
187 .fetch_sheet_id_by_index(p.sheet_idx)
188 .map_err(|l| BasicError::SheetIdxExceed(l))?;
189 let res = delete_block_line(
190 self,
191 sheet_id,
192 p.block_id,
193 false,
194 p.start as u32,
195 p.cnt as u32,
196 ctx,
197 );
198 Ok(res)
199 }
200 EditPayload::InsertRowsInBlock(p) => {
201 let sheet_id = ctx
202 .fetch_sheet_id_by_index(p.sheet_idx)
203 .map_err(|l| BasicError::SheetIdxExceed(l))?;
204 let res = insert_block_line(
205 self,
206 sheet_id,
207 p.block_id,
208 true,
209 p.start as u32,
210 p.cnt as u32,
211 ctx,
212 );
213 Ok(res)
214 }
215 EditPayload::DeleteRowsInBlock(p) => {
216 let sheet_id = ctx
217 .fetch_sheet_id_by_index(p.sheet_idx)
218 .map_err(|l| BasicError::SheetIdxExceed(l))?;
219 let res = delete_block_line(
220 self,
221 sheet_id,
222 p.block_id,
223 true,
224 p.start as u32,
225 p.cnt as u32,
226 ctx,
227 );
228 Ok(res)
229 }
230 _ => Ok(self),
231 }
232 }
233
234 pub fn normal_range_update<F>(mut self, sheet_id: &SheetId, func: &mut F) -> Self
235 where
236 F: FnMut(&NormalRange, &RangeId) -> RangeUpdateType,
237 {
238 let mut to_update = HashSet::new();
239 let mut to_remove = HashSet::new();
240 let manager = self.manager.get_sheet_range_manager(sheet_id);
241 let mut dirty_ranges = self.dirty_ranges;
242 let mut removed_ranges = self.removed_ranges;
243 manager
244 .normal_range_to_id
245 .iter()
246 .for_each(|(range, range_id)| match func(range, range_id) {
247 RangeUpdateType::Dirty => {
248 dirty_ranges.insert((*sheet_id, *range_id));
249 }
250 RangeUpdateType::UpdateTo(new_range) => {
251 dirty_ranges.insert((*sheet_id, new_range.id));
252 to_update.insert(new_range);
253 }
254 RangeUpdateType::None => {}
255 RangeUpdateType::Removed => {
256 to_remove.insert(range_id.clone());
257 dirty_ranges.insert((*sheet_id, *range_id));
258 }
259 });
260 to_update.into_iter().for_each(|new_range| {
261 if let Range::Normal(range) = new_range.range {
262 manager
263 .id_to_normal_range
264 .insert(new_range.id, range.clone());
265 manager.normal_range_to_id.insert(range, new_range.id);
266 }
267 });
268 to_remove.into_iter().for_each(|range_id| {
269 if let Some(data) = manager.id_to_normal_range.get(&range_id) {
270 manager.normal_range_to_id.remove(data);
271 manager.id_to_normal_range.remove(&range_id);
272 removed_ranges.insert((*sheet_id, range_id));
273 }
274 });
275 RangeExecutor {
276 manager: self.manager,
277 removed_ranges,
278 dirty_ranges,
279 }
280 }
281
282 pub fn block_range_update<F>(mut self, sheet_id: &SheetId, func: &mut F) -> Self
283 where
284 F: FnMut(&BlockRange, &RangeId) -> RangeUpdateType,
285 {
286 let mut dirty_ranges = self.dirty_ranges;
287 let mut removed_ranges = self.removed_ranges;
288 let mut to_update = HashSet::new();
289 let mut to_remove = HashSet::new();
290 let manager = self.manager.get_sheet_range_manager(sheet_id);
291 manager
292 .block_range_to_id
293 .iter()
294 .for_each(|(range, range_id)| match func(range, range_id) {
295 RangeUpdateType::Dirty => {
296 dirty_ranges.insert((*sheet_id, *range_id));
297 }
298 RangeUpdateType::UpdateTo(new_range) => {
299 dirty_ranges.insert((*sheet_id, new_range.id));
300 to_update.insert(new_range);
301 }
302 RangeUpdateType::None => {}
303 RangeUpdateType::Removed => {
304 to_remove.insert(range_id.clone());
305 dirty_ranges.insert((*sheet_id, *range_id));
306 }
307 });
308 to_update.into_iter().for_each(|new_range| {
309 if let Range::Block(range) = new_range.range {
310 manager
311 .id_to_block_range
312 .insert(new_range.id, range.clone());
313 manager.block_range_to_id.insert(range, new_range.id);
314 }
315 });
316 to_remove.into_iter().for_each(|range_id| {
317 if let Some(data) = manager.id_to_normal_range.get(&range_id) {
318 manager.normal_range_to_id.remove(data);
319 manager.id_to_normal_range.remove(&range_id);
320 removed_ranges.insert((*sheet_id, range_id));
321 }
322 });
323 RangeExecutor {
324 manager: self.manager,
325 dirty_ranges,
326 removed_ranges,
327 }
328 }
329}
330
331#[derive(Debug, Clone, Hash, Eq, PartialEq)]
332pub struct NewRange {
333 pub id: RangeId,
334 pub range: Range,
335}
336
337pub enum RangeUpdateType {
338 Dirty,
339 UpdateTo(NewRange),
340 None,
341 Removed,
342}