Trait undo::Command[][src]

pub trait Command<R>: Debug + Send + Sync {
    fn apply(
        &mut self,
        receiver: &mut R
    ) -> Result<(), Box<StdError + Send + Sync>>;
fn undo(
        &mut self,
        receiver: &mut R
    ) -> Result<(), Box<StdError + Send + Sync>>; fn redo(
        &mut self,
        receiver: &mut R
    ) -> Result<(), Box<StdError + Send + Sync>> { ... }
fn id(&self) -> Option<u32> { ... } }

Base functionality for all commands.

Required Methods

Applies the command on the receiver and returns Ok if everything went fine, and Err if something went wrong.

Restores the state of the receiver as it was before the command was applied and returns Ok if everything went fine, and Err if something went wrong.

Provided Methods

Reapplies the command on the receiver and return Ok if everything went fine, and Err if something went wrong.

The default implementation uses the apply implementation.

Used for automatic merging of commands.

Two commands are merged together when a command is pushed, and it has the same id as the top command already on the stack or record. When commands are merged together, undoing and redoing them are done in one step.

Examples

#[derive(Debug)]
struct Add(char);

impl Command<String> for Add {
    fn apply(&mut self, s: &mut String) -> Result<(), Box<dyn Error + Send + Sync>> {
        s.push(self.0);
        Ok(())
    }

    fn undo(&mut self, s: &mut String) -> Result<(), Box<dyn Error + Send + Sync>> {
        self.0 = s.pop().ok_or("`s` is empty")?;
        Ok(())
    }

    fn id(&self) -> Option<u32> {
        Some(1)
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let mut record = Record::default();

    // The `a`, `b`, and `c` commands are merged.
    record.apply(Add('a'))?;
    record.apply(Add('b'))?;
    record.apply(Add('c'))?;
    assert_eq!(record.len(), 1);
    assert_eq!(record.as_receiver(), "abc");

    // Calling `undo` once will undo all merged commands.
    record.undo().unwrap()?;
    assert_eq!(record.as_receiver(), "");

    // Calling `redo` once will redo all merged commands.
    record.redo().unwrap()?;
    assert_eq!(record.as_receiver(), "abc");

    Ok(())
}

Implementations on Foreign Types

impl<R, C: Command<R> + ?Sized> Command<R> for Box<C>
[src]

Implementors