1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
use std::fmt; #[derive(Debug, PartialOrd, PartialEq)] pub enum Calc<T> { Val(T), Sum(Box<Calc<T>>, T), Sub(Box<Calc<T>>, T), Mul(Box<Calc<T>>, T), Div(Box<Calc<T>>, T), } impl<T: Clone> Clone for Calc<T> { fn clone(&self) -> Self { match self { Self::Val(v) => Self::Val(v.clone()), Self::Sum(c, v) => Self::Sum(c.clone(), v.clone()), Self::Sub(c, v) => Self::Sub(c.clone(), v.clone()), Self::Mul(c, v) => Self::Mul(c.clone(), v.clone()), Self::Div(c, v) => Self::Div(c.clone(), v.clone()), } } } impl<T: fmt::Display> fmt::Display for Calc<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt_calc<T: fmt::Display>(calc: &Calc<T>) -> String { match calc { Calc::Val(val) => format!("{}", val), Calc::Sum(c, val) => format!("({} + {})", fmt_calc(c), val), Calc::Sub(c, val) => format!("({} - {})", fmt_calc(c), val), Calc::Mul(c, val) => format!("({} * {})", fmt_calc(c), val), Calc::Div(c, val) => format!("({} / {})", fmt_calc(c), val), } } match self { Self::Val(_) => write!(f, "calc({})", fmt_calc(self)), _ => write!(f, "calc{}", fmt_calc(self)), } } } impl<T> Calc<T> { pub fn sum(self, val: impl Into<T>) -> Self { Self::Sum(Box::new(self), val.into()) } pub fn sub(self, val: impl Into<T>) -> Self { Self::Sub(Box::new(self), val.into()) } pub fn mul(self, val: impl Into<T>) -> Self { Self::Mul(Box::new(self), val.into()) } pub fn div(self, val: impl Into<T>) -> Self { Self::Div(Box::new(self), val.into()) } } pub fn calc<T>(val: impl Into<T>, f: impl FnOnce(Calc<T>) -> Calc<T>) -> Calc<T> { f(Calc::Val(val.into())) }