use buffer::operation::Operation;
pub struct History {
previous: Vec<Box<Operation>>,
next: Vec<Box<Operation>>,
}
impl History {
pub fn new() -> History {
History{ previous: Vec::new(), next: Vec::new() }
}
pub fn add(&mut self, operation: Box<Operation>) {
self.previous.push(operation);
self.next.clear();
}
pub fn previous(&mut self) -> Option<Box<Operation>> {
match self.previous.pop() {
Some(operation) => {
self.next.push(operation.clone_operation());
Some(operation)
},
None => None
}
}
pub fn next(&mut self) -> Option<Box<Operation>> {
match self.next.pop() {
Some(operation) => {
self.previous.push(operation.clone_operation());
Some(operation)
},
None => None
}
}
}
#[cfg(test)]
mod tests {
use super::History;
use buffer::{Buffer, Position};
use buffer::operations::Insert;
use buffer::operation::Operation;
#[test]
fn previous_and_next_return_the_correct_operations() {
let mut history = History::new();
let mut buffer = Buffer::new();
let insert_position = Position{ line: 0, offset: 0 };
let mut insert_operation = Insert::new("scribe".to_string(), insert_position);
insert_operation.run(&mut buffer);
history.add(Box::new(insert_operation));
assert_eq!(buffer.data(), "scribe");
match history.previous() {
Some(mut operation) => operation.reverse(&mut buffer),
None => (),
};
assert_eq!(buffer.data(), "");
match history.next() {
Some(mut operation) => operation.run(&mut buffer),
None => (),
};
assert_eq!(buffer.data(), "scribe");
match history.previous() {
Some(mut operation) => operation.reverse(&mut buffer),
None => (),
};
assert_eq!(buffer.data(), "");
}
#[test]
fn adding_a_new_operation_clears_redo_stack() {
let mut history = History::new();
let insert_position = Position{ line: 0, offset: 0 };
let insert_operation = Insert::new("scribe".to_string(), insert_position);
history.add(Box::new(insert_operation));
assert!(history.previous().is_some());
let second_insert_operation = Insert::new("scribe".to_string(), insert_position);
history.add(Box::new(second_insert_operation));
assert!(history.next().is_none());
}
}