Trait redo::Command [] [src]

pub trait Command<R> {
    type Err;
    fn exec(&mut self, receiver: &mut R) -> Result<(), Self::Err>;
fn undo(&mut self, receiver: &mut R) -> Result<(), Self::Err>; fn merge(&mut self, cmd: Self) -> Result<(), Self>
    where
        Self: Sized
, { ... } }

Base functionality for all commands.

Associated Types

The error type.

Required Methods

Executes the desired command and returns Ok if everything went fine, and Err if something went wrong.

Restores the state as it was before exec was called and returns Ok if everything went fine, and Err if something went wrong.

Provided Methods

Used for manual merging of two commands.

Returns Ok if commands was merged and Err if not.

Examples

use redo::{Command, Error, Stack};

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

impl Command<String> for Add {
    type Err = ();

    fn exec(&mut self, s: &mut String) -> Result<(), ()> {
        s.push_str(&self.0);
        Ok(())
    }

    fn undo(&mut self, s: &mut String) -> Result<(), ()> {
        let len = s.len() - self.0.len();
        s.truncate(len);
        Ok(())
    }

    fn merge(&mut self, Add(s): Self) -> Result<(), Self> {
        self.0.push_str(&s);
        Ok(())
    }
}

fn foo() -> Result<(), Error<String, Add>> {
    let mut stack = Stack::default();

    // "a", "b", and "c" are merged.
    stack.push(Add("a".into()))?;
    stack.push(Add("b".into()))?;
    stack.push(Add("c".into()))?;
    assert_eq!(stack.len(), 1);
    assert_eq!(stack.as_receiver(), "abc");

    // Calling `pop` once will undo all merged commands.
    let abc = stack.pop().unwrap()?;
    assert_eq!(stack.as_receiver(), "");

    // Pushing the merged commands back on the stack will redo them.
    stack.push(abc)?;
    assert_eq!(stack.into_receiver(), "abc");

    Ok(())
}

Implementors