use actions::InverseResult;
use actions::State;
struct Counter(u32);
#[derive(Debug)]
enum CounterAction {
Increment,
Decrement,
}
#[derive(Debug)]
enum CounterError {
MinValueReached,
MaxValueReached,
}
impl State for Counter {
type Action = CounterAction;
type Error = CounterError;
fn apply(&mut self, action: &CounterAction) -> Result<(), CounterError> {
match action {
CounterAction::Increment => {
if self.0 == <u32>::max_value() {
return Err(CounterError::MaxValueReached);
}
self.0 += 1;
}
CounterAction::Decrement => {
if self.0 == <u32>::min_value() {
return Err(CounterError::MinValueReached);
}
self.0 -= 1;
}
}
Ok(())
}
fn inverse(&self, action: &CounterAction) -> InverseResult<CounterAction> {
let inverse = match action {
CounterAction::Increment => CounterAction::Decrement,
CounterAction::Decrement => CounterAction::Increment,
};
InverseResult::Action(inverse)
}
}
fn test() -> Result<(), CounterError> {
let mut counter = Counter(0);
let mut undo = vec![];
let action = CounterAction::Increment;
if let InverseResult::Action(inverse) = counter.inverse(&action) {
undo.push(inverse);
}
counter.apply(&action)?;
assert_eq!(counter.0, 1);
println!("After action \"{:?}\": {}", action, counter.0);
let action = CounterAction::Increment;
if let InverseResult::Action(inverse) = counter.inverse(&action) {
undo.push(inverse);
}
counter.apply(&action)?;
assert_eq!(counter.0, 2);
println!("After action \"{:?}\": {}", action, counter.0);
let action = CounterAction::Increment;
if let InverseResult::Action(inverse) = counter.inverse(&action) {
undo.push(inverse);
}
counter.apply(&action)?;
assert_eq!(counter.0, 3);
println!("After action \"{:?}\": {}", action, counter.0);
counter.apply(&undo.pop().unwrap())?;
println!("After undo: {}", counter.0);
counter.apply(&undo.pop().unwrap())?;
println!("After undo: {}", counter.0);
counter.apply(&undo.pop().unwrap())?;
println!("After undo: {}", counter.0);
Ok(())
}
pub fn main() {
if let Err(e) = test() {
eprintln!("Error: {:?}", e);
};
}