@@ -57,37 +57,31 @@ impl History {
5757 self.cursor == 0
5858 }
5959
60− pub fn undo(&mut self, state: &mut State) {
60+ // TODO: I'd like to pass Transaction by reference but it fights with the borrowck
61+
62+ pub fn undo(&mut self) -> Option<Transaction> {
6163 if self.at_root() {
6264 // We're at the root of undo, nothing to do.
63− return;
65+ return None;
6466 }
6567
6668 let current_revision = &self.revisions[self.cursor];
6769
68− // TODO: pass the return value through? It should always succeed
69− let success = current_revision.revert.apply(state);
70−
71− if !success {
72− panic!("Failed to apply undo!");
73− }
74−
7570 self.cursor = current_revision.parent;
71+
72+ Some(current_revision.revert.clone())
7673 }
7774
78− pub fn redo(&mut self, state: &mut State) {
75+ pub fn redo(&mut self) -> Option<Transaction> {
7976 let current_revision = &self.revisions[self.cursor];
8077
8178 // for now, simply pick the latest child (linear undo / redo)
8279 if let Some((index, transaction)) = current_revision.children.last() {
83− let success = transaction.apply(state);
84−
85− if !success {
86− panic!("Failed to apply redo!");
87− }
88−
8980 self.cursor = *index;
81+
82+ return Some(transaction.clone());
9083 }
84+ None
9185 }
9286}
9387
@@ -120,17 +114,27 @@ mod test {
120114 assert_eq!("hello 世界!", state.doc());
121115
122116 // ---
117+ fn undo(history: &mut History, state: &mut State) {
118+ if let Some(transaction) = history.undo() {
119+ transaction.apply(state);
120+ }
121+ }
122+ fn redo(history: &mut History, state: &mut State) {
123+ if let Some(transaction) = history.redo() {
124+ transaction.apply(state);
125+ }
126+ }
123127
124− history.undo(&mut state);
128+ undo(&mut history, &mut state);
125129 assert_eq!("hello world!", state.doc());
126− history.redo(&mut state);
130+ redo(&mut history, &mut state);
127131 assert_eq!("hello 世界!", state.doc());
128− history.undo(&mut state);
129− history.undo(&mut state);
132+ undo(&mut history, &mut state);
133+ undo(&mut history, &mut state);
130134 assert_eq!("hello", state.doc());
131135
132136 // undo at root is a no-op
133− history.undo(&mut state);
137+ undo(&mut history, &mut state);
134138 assert_eq!("hello", state.doc());
135139 }
136140}