pub trait Command<R> {
type Error;
fn apply(&mut self, receiver: &mut R) -> Result<(), Self::Error>;
fn undo(&mut self, receiver: &mut R) -> Result<(), Self::Error>;
fn redo(&mut self, receiver: &mut R) -> Result<(), Self::Error> { ... }
fn merge(&mut self, command: Self) -> Merge<Self>
where
Self: Sized,
{ ... }
}
Expand description
Base functionality for all commands.
Required Associated Types
Required Methods
Provided Methods
sourcefn redo(&mut self, receiver: &mut R) -> Result<(), Self::Error>
fn redo(&mut self, receiver: &mut R) -> Result<(), Self::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.
sourcefn merge(&mut self, command: Self) -> Merge<Self>where
Self: Sized,
fn merge(&mut self, command: Self) -> Merge<Self>where
Self: Sized,
Used for manual merging of two commands.
Examples
#[derive(Debug)]
struct Add(String);
impl Command<String> for Add {
type Error = ();
fn apply(&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) -> Merge<Self> {
self.0.push_str(&s);
Merge::Yes
}
}
fn main() -> redo::Result<String, Add> {
let mut record = Record::default();
// The `a`, `b`, and `c` commands are merged.
record.apply(Add("a".into()))?;
record.apply(Add("b".into()))?;
record.apply(Add("c".into()))?;
assert_eq!(record.as_receiver(), "abc");
// Calling `undo` once will undo all the merged commands.
record.undo().unwrap()?;
assert_eq!(record.as_receiver(), "");
// Calling `redo` once will redo all the merged commands.
record.redo().unwrap()?;
assert_eq!(record.as_receiver(), "abc");
Ok(())
}