use std::ops::{Add, Div, Mul, Sub};
pub struct Calculator<Value: Add + Sub + Div + Mul + Copy> {
init: Value,
actions: Vec<Action<Value>>,
}
#[derive(Clone, Copy)]
pub enum Action<Value: Add + Sub + Div + Mul + Copy> {
Add(Value),
Sub(Value),
Mul(Value),
Div(Value),
}
impl<Value> Calculator<Value>
where
Value: Add<Output = Value>
+ Sub<Output = Value>
+ Div<Output = Value>
+ Mul<Output = Value>
+ Copy,
{
pub fn new(value: Value) -> Self {
Self {
init: value,
actions: Vec::new(),
}
}
pub fn apply(&mut self, action: Action<Value>) -> &mut Self {
self.actions.push(action);
self
}
pub fn replay(&mut self) -> &mut Self {
let last_action = *self.actions.last().unwrap();
self.apply(last_action);
self
}
pub fn undo(&mut self) -> &mut Self {
self.actions.pop();
self
}
pub fn result(&self) -> Value {
(&self.actions)
.into_iter()
.fold(self.init, |acc, action| match action {
Action::Add(v) => acc + *v,
Action::Sub(v) => acc - *v,
Action::Mul(v) => acc * *v,
Action::Div(v) => acc / *v,
})
}
}