Trait undo::Command [−][src]
pub trait Command<R>: Debug + Send + Sync { fn apply(&mut self, receiver: &mut R) -> Result<(), Box<Error>>; fn undo(&mut self, receiver: &mut R) -> Result<(), Box<Error>>; fn redo(&mut self, receiver: &mut R) -> Result<(), Box<Error>> { ... } fn id(&self) -> Option<u32> { ... } }
Base functionality for all commands.
Required Methods
fn apply(&mut self, receiver: &mut R) -> Result<(), Box<Error>>
Applies the command on the receiver and returns Ok
if everything went fine,
and Err
if something went wrong.
fn undo(&mut self, receiver: &mut R) -> Result<(), Box<Error>>
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
fn redo(&mut self, receiver: &mut R) -> Result<(), Box<Error>>
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.
fn id(&self) -> Option<u32>
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<Error>> { s.push(self.0); Ok(()) } fn undo(&mut self, s: &mut String) -> Result<(), Box<Error>> { self.0 = s.pop().ok_or("`String` is unexpectedly empty")?; Ok(()) } fn id(&self) -> Option<u32> { Some(1) } } fn main() -> Result<(), Box<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.into_receiver(), "abc"); Ok(()) }
Implementations on Foreign Types
impl<R, C: Command<R> + ?Sized> Command<R> for Box<C>
[src]
impl<R, C: Command<R> + ?Sized> Command<R> for Box<C>