formualizer_workbook/
session.rs1use crate::error::IoError;
2use formualizer_eval::engine::graph::DependencyGraph;
3use formualizer_eval::engine::graph::editor::change_log::ChangeLog;
4use formualizer_eval::engine::graph::editor::undo_engine::UndoEngine;
5use formualizer_eval::engine::graph::editor::vertex_editor::{EditorError, VertexEditor};
6
7#[derive(Clone, Debug)]
9pub struct IoConfig {
10 pub enable_changelog: bool,
12}
13
14impl Default for IoConfig {
15 fn default() -> Self {
16 Self {
17 enable_changelog: true,
18 }
19 }
20}
21
22pub struct EditorSession {
24 pub graph: DependencyGraph,
25 enable_changelog: bool,
26 log: ChangeLog,
27 undo: UndoEngine,
28}
29
30impl EditorSession {
31 pub fn new_with_graph(graph: DependencyGraph, cfg: IoConfig) -> Self {
32 let mut log = ChangeLog::new();
33 log.set_enabled(cfg.enable_changelog);
34 Self {
35 graph,
36 enable_changelog: cfg.enable_changelog,
37 log,
38 undo: UndoEngine::new(),
39 }
40 }
41
42 pub fn new(cfg: IoConfig) -> Self {
43 Self::new_with_graph(DependencyGraph::new(), cfg)
44 }
45
46 pub fn begin_action(&mut self, description: impl Into<String>) {
48 if self.enable_changelog {
49 self.log.begin_compound(description.into());
50 }
51 }
52
53 pub fn end_action(&mut self) {
55 if self.enable_changelog {
56 self.log.end_compound();
57 }
58 }
59
60 pub fn with_action<F, R>(
62 &mut self,
63 description: impl Into<String>,
64 f: F,
65 ) -> Result<R, EditorError>
66 where
67 F: FnOnce(&mut VertexEditor) -> Result<R, EditorError>,
68 {
69 self.begin_action(description);
70 let res = {
71 let mut editor = self.make_editor();
72 f(&mut editor)
73 };
74 self.end_action();
75 res
76 }
77
78 pub fn make_editor(&mut self) -> VertexEditor<'_> {
80 if self.enable_changelog {
81 VertexEditor::with_logger(&mut self.graph, &mut self.log)
82 } else {
83 VertexEditor::new(&mut self.graph)
84 }
85 }
86
87 pub fn undo(&mut self) -> Result<(), EditorError> {
89 if self.enable_changelog {
90 let _ = self.undo.undo(&mut self.graph, &mut self.log)?;
91 Ok(())
92 } else {
93 Ok(())
94 }
95 }
96
97 pub fn redo(&mut self) -> Result<(), EditorError> {
99 if self.enable_changelog {
100 let _ = self.undo.redo(&mut self.graph, &mut self.log)?;
101 Ok(())
102 } else {
103 Ok(())
104 }
105 }
106
107 pub fn commit_with_rollback<F>(&mut self, persist: F) -> Result<(), IoError>
109 where
110 F: FnOnce(&DependencyGraph) -> Result<(), IoError>,
111 {
112 match persist(&self.graph) {
113 Ok(()) => Ok(()),
114 Err(e) => {
115 if self.enable_changelog {
116 let _ = self.undo();
118 }
119 Err(e)
120 }
121 }
122 }
123
124 pub fn changelog_enabled(&self) -> bool {
126 self.enable_changelog
127 }
128}