Crate undo [] [src]

A undo/redo library.

It uses the Command Pattern where the user implements the UndoCmd trait for each command and then the commands can be used with the UndoStack.

The UndoStack has two different states, clean and dirty. The stack is in a clean state when there are no more commands that can be redone, otherwise it's in a dirty state. The stack can be configured to call a given method when this state changes, using the on_clean and on_dirty methods.

The UndoStack also supports easy merging of commands by just implementing the id method for a given command.

Example

use std::rc::Rc;
use std::cell::RefCell;
use undo::{UndoCmd, UndoStack};

/// Pops an element from a vector.
#[derive(Clone)]
struct PopCmd {
    vec: Rc<RefCell<Vec<i32>>>,
    e: Option<i32>,
}

impl UndoCmd for PopCmd {
    fn redo(&mut self) {
        self.e = self.vec.borrow_mut().pop();
    }

    fn undo(&mut self) {
        self.vec.borrow_mut().push(self.e.unwrap());
        self.e = None;
    }
}

// We need to use Rc<RefCell> since all commands are going to mutate the vec.
let vec = Rc::new(RefCell::new(vec![1, 2, 3]));
let mut stack = UndoStack::new()
    .on_clean(|| println!("This is called when the stack changes from dirty to clean!"))
    .on_dirty(|| println!("This is called when the stack changes from clean to dirty!"));

let cmd = PopCmd { vec: vec.clone(), e: None };
stack.push(cmd.clone());
stack.push(cmd.clone());
stack.push(cmd.clone());

assert!(vec.borrow().is_empty());

stack.undo(); // on_dirty is going to be called here.
stack.undo();
stack.undo();

assert_eq!(vec.borrow().len(), 3);

Structs

Uid

An unique id for an UndoStack.

UndoGroup

A collection of UndoStacks.

UndoStack

UndoStack maintains a stack of UndoCmds that can be undone and redone by using methods on the UndoStack.

Traits

UndoCmd

Every command needs to implement the UndoCmd trait to be able to be used with the UndoStack.