formualizer_workbook/
transaction.rs1use crate::traits::{CellData, SpreadsheetWriter};
2use std::collections::BTreeMap;
3
4#[derive(Clone, Debug)]
6pub enum WriteOp {
7 Cell {
8 sheet: String,
9 row: u32,
10 col: u32,
11 data: CellData,
12 },
13 Range {
14 sheet: String,
15 cells: BTreeMap<(u32, u32), CellData>,
16 },
17 Clear {
18 sheet: String,
19 start: (u32, u32),
20 end: (u32, u32),
21 },
22 CreateSheet {
23 name: String,
24 },
25 DeleteSheet {
26 name: String,
27 },
28 RenameSheet {
29 old: String,
30 new: String,
31 },
32}
33
34pub struct WriteTransaction<'a, W: SpreadsheetWriter> {
38 writer: &'a mut W,
39 operations: Vec<WriteOp>,
40 committed: bool,
41 validated: bool,
42}
43
44impl<'a, W: SpreadsheetWriter> WriteTransaction<'a, W> {
45 pub fn new(writer: &'a mut W) -> Self {
46 Self {
47 writer,
48 operations: Vec::new(),
49 committed: false,
50 validated: false,
51 }
52 }
53
54 pub fn write_cell(&mut self, sheet: &str, row: u32, col: u32, data: CellData) -> &mut Self {
55 self.operations.push(WriteOp::Cell {
56 sheet: sheet.to_string(),
57 row,
58 col,
59 data,
60 });
61 self
62 }
63
64 pub fn write_range(&mut self, sheet: &str, cells: BTreeMap<(u32, u32), CellData>) -> &mut Self {
65 self.operations.push(WriteOp::Range {
66 sheet: sheet.to_string(),
67 cells,
68 });
69 self
70 }
71
72 pub fn clear_range(&mut self, sheet: &str, start: (u32, u32), end: (u32, u32)) -> &mut Self {
73 self.operations.push(WriteOp::Clear {
74 sheet: sheet.to_string(),
75 start,
76 end,
77 });
78 self
79 }
80
81 pub fn create_sheet(&mut self, name: &str) -> &mut Self {
82 self.operations.push(WriteOp::CreateSheet {
83 name: name.to_string(),
84 });
85 self
86 }
87
88 pub fn delete_sheet(&mut self, name: &str) -> &mut Self {
89 self.operations.push(WriteOp::DeleteSheet {
90 name: name.to_string(),
91 });
92 self
93 }
94
95 pub fn rename_sheet(&mut self, old: &str, new: &str) -> &mut Self {
96 self.operations.push(WriteOp::RenameSheet {
97 old: old.to_string(),
98 new: new.to_string(),
99 });
100 self
101 }
102
103 pub fn validate(&mut self) -> Result<(), W::Error> {
105 self.validated = true; Ok(())
107 }
108
109 pub fn commit(mut self) -> Result<(), W::Error> {
111 if self.committed {
112 return Ok(());
113 }
114 if !self.validated {
115 self.validate()?;
116 }
117 for op in &self.operations {
118 match op {
119 WriteOp::Cell {
120 sheet,
121 row,
122 col,
123 data,
124 } => {
125 self.writer.write_cell(sheet, *row, *col, data.clone())?;
126 }
127 WriteOp::Range { sheet, cells } => {
128 self.writer.write_range(sheet, cells.clone())?;
129 }
130 WriteOp::Clear { sheet, start, end } => {
131 self.writer.clear_range(sheet, *start, *end)?;
132 }
133 WriteOp::CreateSheet { name } => {
134 self.writer.create_sheet(name)?;
135 }
136 WriteOp::DeleteSheet { name } => {
137 self.writer.delete_sheet(name)?;
138 }
139 WriteOp::RenameSheet { old, new } => {
140 self.writer.rename_sheet(old, new)?;
141 }
142 }
143 }
144 self.writer.flush()?;
146 self.writer.save()?;
148 self.committed = true;
149 Ok(())
150 }
151
152 pub fn rollback(mut self) {
154 self.committed = true;
155 }
156
157 pub fn operations(&self) -> &[WriteOp] {
158 &self.operations
159 }
160}
161
162impl<'a, W: SpreadsheetWriter> Drop for WriteTransaction<'a, W> {
163 fn drop(&mut self) {
164 }
166}