diff --git a/src/calc/entries.rs b/src/calc/entries.rs index cd75ae6..6e2df79 100644 --- a/src/calc/entries.rs +++ b/src/calc/entries.rs @@ -54,16 +54,22 @@ impl VectorDirection { #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct Vector { - pub direction: VectorDirection, pub values: Vec, + pub direction: VectorDirection, } +// #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] +// pub struct Matrix { +// pub values: Vec, +// pub direction: VectorDirection, +// } + #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[serde(tag = "type")] pub enum Entry { Number(Number), Vector(Vector), - // Matrix(Vec), + // Matrix(Matrix), } // macro_rules! op_child_call { @@ -174,131 +180,45 @@ impl CalculatorEntry for Entry { } fn add(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.add_num(number), - Self::Vector(vector) => self.add_vec(vector), + match self { + Self::Number(number) => number.add(arg), + Self::Vector(vector) => vector.add(arg), } } fn sub(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.sub_num(number), - Self::Vector(vector) => self.sub_vec(vector), + match self { + Self::Number(number) => number.sub(arg), + Self::Vector(vector) => vector.sub(arg), } } fn mul(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.mul_num(number), - Self::Vector(vector) => self.mul_vec(vector), + match self { + Self::Number(number) => number.mul(arg), + Self::Vector(vector) => vector.mul(arg), } } fn div(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.div_num(number), - Self::Vector(vector) => self.div_vec(vector), + match self { + Self::Number(number) => number.div(arg), + Self::Vector(vector) => vector.div(arg), } } fn int_divide(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.int_divide_num(number), - Self::Vector(vector) => self.int_divide_vec(vector), + match self { + Self::Number(number) => number.int_divide(arg), + Self::Vector(vector) => vector.int_divide(arg), } } fn modulo(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.modulo_num(number), - Self::Vector(vector) => self.modulo_vec(vector), + match self { + Self::Number(number) => number.modulo(arg), + Self::Vector(vector) => vector.modulo(arg), } } fn pow(&self, arg: &Self) -> CalculatorResult { - match arg { - Self::Number(number) => self.pow_num(number), - Self::Vector(vector) => self.pow_vec(vector), - } - } - - fn add_vec(&self, arg: &Vector) -> CalculatorResult { match self { - Self::Number(number) => number.add_vec(arg), - Self::Vector(vector) => vector.add_vec(arg), - } - } - fn sub_vec(&self, arg: &Vector) -> CalculatorResult { - match self { - Self::Number(number) => number.sub_vec(arg), - Self::Vector(vector) => vector.sub_vec(arg), - } - } - fn mul_vec(&self, arg: &Vector) -> CalculatorResult { - match self { - Self::Number(number) => number.mul_vec(arg), - Self::Vector(vector) => vector.mul_vec(arg), - } - } - fn div_vec(&self, arg: &Vector) -> CalculatorResult { - match self { - Self::Number(number) => number.div_vec(arg), - Self::Vector(vector) => vector.div_vec(arg), - } - } - fn int_divide_vec(&self, arg: &Vector) -> CalculatorResult { - match self { - Self::Number(number) => number.int_divide_vec(arg), - Self::Vector(vector) => vector.int_divide_vec(arg), - } - } - fn modulo_vec(&self, arg: &Vector) -> CalculatorResult { - match self { - Self::Number(number) => number.modulo_vec(arg), - Self::Vector(vector) => vector.modulo_vec(arg), - } - } - fn pow_vec(&self, arg: &Vector) -> CalculatorResult { - match self { - Self::Number(number) => number.pow_vec(arg), - Self::Vector(vector) => vector.pow_vec(arg), - } - } - - fn add_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.add_num(arg), - Self::Vector(vector) => vector.add_num(arg), - } - } - fn sub_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.sub_num(arg), - Self::Vector(vector) => vector.sub_num(arg), - } - } - fn mul_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.mul_num(arg), - Self::Vector(vector) => vector.mul_num(arg), - } - } - fn div_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.div_num(arg), - Self::Vector(vector) => vector.div_num(arg), - } - } - fn int_divide_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.int_divide_num(arg), - Self::Vector(vector) => vector.int_divide_num(arg), - } - } - fn modulo_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.modulo_num(arg), - Self::Vector(vector) => vector.modulo_num(arg), - } - } - fn pow_num(&self, arg: &Number) -> CalculatorResult { - match self { - Self::Number(number) => number.pow_num(arg), - Self::Vector(vector) => vector.pow_num(arg), + Self::Number(number) => number.pow(arg), + Self::Vector(vector) => vector.pow(arg), } } } @@ -331,7 +251,7 @@ impl CalculatorEntry for Vector { .values .iter() .try_fold(Entry::Number(Number::ZERO), |acc, n2| { - acc.add(&n2.pow_num(&Number { value: 2.0_f64 })?) + acc.add(&n2.pow(&Entry::Number(Number { value: 2.0_f64 }))?) })?; value.sqrt() } @@ -371,110 +291,68 @@ impl CalculatorEntry for Vector { fn add(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.add_vec(vector), - Entry::Number(number) => self.add_num(number), + Entry::Vector(v2) => self.iterated_binary_vec(v2, Number::add), + Entry::Number(number) => self.iterated_binary_num(number, Number::add), } } fn sub(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.sub_vec(vector), - Entry::Number(number) => self.sub_num(number), + Entry::Vector(v2) => self.iterated_binary_vec(v2, Number::sub), + Entry::Number(number) => self.iterated_binary_num(number, Number::sub), } } fn mul(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.mul_vec(vector), - Entry::Number(number) => self.mul_num(number), + Entry::Vector(v2) => { + if self.values.len() != v2.values.len() { + return Err(CalculatorError::DimensionMismatch); + } + match (self.direction, v2.direction) { + (VectorDirection::Row, VectorDirection::Column) => { + // Row by column -- will produce a scalar + self.values + .iter() + .zip(v2.values.iter()) + .try_fold(Entry::Number(Number::ZERO), |acc, (n1, n2)| { + acc.add(&n1.mul(&Entry::Number(*n2))?) + }) + } + (VectorDirection::Column, VectorDirection::Row) => { + Err(CalculatorError::NotYetImplemented) + } + (VectorDirection::Row, VectorDirection::Row) + | (VectorDirection::Column, VectorDirection::Column) => { + Err(CalculatorError::DimensionMismatch) + } + } + } + Entry::Number(number) => self.iterated_binary_num(number, Number::mul), } } fn div(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.div_vec(vector), - Entry::Number(number) => self.div_num(number), + Entry::Vector(v2) => self.iterated_binary_vec(v2, Number::div), + Entry::Number(number) => self.iterated_binary_num(number, Number::div), } } fn int_divide(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.int_divide_vec(vector), - Entry::Number(number) => self.int_divide_num(number), + Entry::Vector(v2) => self.iterated_binary_vec(v2, Number::int_divide), + Entry::Number(number) => self.iterated_binary_num(number, Number::int_divide), } } fn modulo(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.modulo_vec(vector), - Entry::Number(number) => self.modulo_num(number), + Entry::Vector(v2) => self.iterated_binary_vec(v2, Number::modulo), + Entry::Number(number) => self.iterated_binary_num(number, Number::modulo), } } fn pow(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.pow_vec(vector), - Entry::Number(number) => self.pow_num(number), + Entry::Vector(v2) => self.iterated_binary_vec(v2, Number::pow), + Entry::Number(number) => self.iterated_binary_num(number, Number::pow), } } - - fn add_vec(&self, arg: &Self) -> CalculatorResult { - self.iterated_binary_vec(arg, Number::add_num) - } - fn sub_vec(&self, arg: &Self) -> CalculatorResult { - self.iterated_binary_vec(arg, Number::sub_num) - } - fn mul_vec(&self, arg: &Self) -> CalculatorResult { - if self.values.len() != arg.values.len() { - return Err(CalculatorError::DimensionMismatch); - } - match (self.direction, arg.direction) { - (VectorDirection::Row, VectorDirection::Column) => { - // Row by column -- will produce a scalar - self.values - .iter() - .zip(arg.values.iter()) - .try_fold(Entry::Number(Number::ZERO), |acc, (n1, n2)| { - acc.add(&n1.mul_num(n2)?) - }) - } - (VectorDirection::Column, VectorDirection::Row) => { - Err(CalculatorError::NotYetImplemented) - } - (VectorDirection::Row, VectorDirection::Row) - | (VectorDirection::Column, VectorDirection::Column) => { - Err(CalculatorError::DimensionMismatch) - } - } - } - fn div_vec(&self, arg: &Self) -> CalculatorResult { - self.iterated_binary_vec(arg, Number::div_num) - } - fn int_divide_vec(&self, arg: &Self) -> CalculatorResult { - self.iterated_binary_vec(arg, Number::int_divide_num) - } - fn modulo_vec(&self, arg: &Self) -> CalculatorResult { - self.iterated_binary_vec(arg, Number::modulo_num) - } - fn pow_vec(&self, arg: &Self) -> CalculatorResult { - self.iterated_binary_vec(arg, Number::pow_num) - } - - fn add_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::add_num) - } - fn sub_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::sub_num) - } - fn mul_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::mul_num) - } - fn div_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::div_num) - } - fn int_divide_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::int_divide_num) - } - fn modulo_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::modulo_num) - } - fn pow_num(&self, arg: &Number) -> CalculatorResult { - self.iterated_binary_num(arg, Number::pow_num) - } } impl Vector { @@ -500,7 +378,7 @@ impl Vector { fn iterated_binary_vec( &self, v2: &Self, - op: impl Fn(&Number, &Number) -> CalculatorResult, + op: impl Fn(&Number, &Entry) -> CalculatorResult, ) -> CalculatorResult { if self.values.len() != v2.values.len() { return Err(CalculatorError::DimensionMismatch); @@ -513,7 +391,7 @@ impl Vector { .values .iter() .zip(v2.values.iter()) - .map(|(n1, n2)| op(n1, n2)) + .map(|(n1, n2)| op(n1, &Entry::Number(*n2))) .map(|e| match e { // Only numbers are valid in a vector Ok(Entry::Number(number)) => Ok(number), @@ -526,13 +404,13 @@ impl Vector { fn iterated_binary_num( &self, n2: &Number, - op: impl Fn(&Number, &Number) -> CalculatorResult, + op: impl Fn(&Number, &Entry) -> CalculatorResult, ) -> CalculatorResult { Ok(Entry::Vector(Self { values: self .values .iter() - .map(|n| op(n, n2)) + .map(|n| op(n, &Entry::Number(*n2))) .map(|e| match e { // Only numbers are valid in a vector Ok(Entry::Number(number)) => Ok(number), @@ -647,111 +525,67 @@ impl CalculatorEntry for Number { fn add(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.add_vec(vector), - Entry::Number(number) => self.add_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::add), + Entry::Number(number) => Self { + value: self.value + number.value, + } + .validate(), } } fn sub(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.sub_vec(vector), - Entry::Number(number) => self.sub_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::sub), + Entry::Number(number) => Self { + value: self.value - number.value, + } + .validate(), } } fn mul(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.mul_vec(vector), - Entry::Number(number) => self.mul_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::mul), + Entry::Number(number) => Self { + value: self.value * number.value, + } + .validate(), } } fn div(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.div_vec(vector), - Entry::Number(number) => self.div_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::div), + Entry::Number(number) => Self { + value: self.value / number.value, + } + .validate(), } } fn int_divide(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.int_divide_vec(vector), - Entry::Number(number) => self.int_divide_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::int_divide), + Entry::Number(number) => Self { + value: self.value.div_euclid(number.value), + } + .validate(), } } fn modulo(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.modulo_vec(vector), - Entry::Number(number) => self.modulo_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::modulo), + Entry::Number(number) => Self { + value: self.value % number.value, + } + .validate(), } } fn pow(&self, arg: &Entry) -> CalculatorResult { match arg { - Entry::Vector(vector) => self.pow_vec(vector), - Entry::Number(number) => self.pow_num(number), + Entry::Vector(vector) => self.iterated_binary(vector, Self::pow), + Entry::Number(number) => Self { + value: self.value.powf(number.value), + } + .validate(), } } - - fn add_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::add_num) - } - fn sub_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::sub_num) - } - fn mul_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::mul_num) - } - fn div_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::div_num) - } - fn int_divide_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::int_divide_num) - } - fn modulo_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::modulo_num) - } - fn pow_vec(&self, arg: &Vector) -> CalculatorResult { - self.iterated_binary(arg, Self::pow_num) - } - - fn add_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value + arg.value, - } - .validate() - } - fn sub_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value - arg.value, - } - .validate() - } - fn mul_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value * arg.value, - } - .validate() - } - fn div_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value / arg.value, - } - .validate() - } - fn int_divide_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value.div_euclid(arg.value), - } - .validate() - } - fn modulo_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value % arg.value, - } - .validate() - } - fn pow_num(&self, arg: &Number) -> CalculatorResult { - Self { - value: self.value.powf(arg.value), - } - .validate() - } } impl Number { @@ -768,13 +602,13 @@ impl Number { fn iterated_binary( self, vector: &Vector, - op: impl Fn(&Self, &Self) -> CalculatorResult, + op: impl Fn(&Self, &Entry) -> CalculatorResult, ) -> CalculatorResult { Ok(Entry::Vector(Vector { values: vector .values .iter() - .map(|n| op(&self, n)) + .map(|n| op(&self, &Entry::Number(*n))) .map(|e| match e { // Only numbers are valid in a vector Ok(Entry::Number(number)) => Ok(number), @@ -804,22 +638,6 @@ where fn modulo(&self, arg: &Entry) -> CalculatorResult; fn pow(&self, arg: &Entry) -> CalculatorResult; - fn add_vec(&self, arg: &Vector) -> CalculatorResult; - fn sub_vec(&self, arg: &Vector) -> CalculatorResult; - fn mul_vec(&self, arg: &Vector) -> CalculatorResult; - fn div_vec(&self, arg: &Vector) -> CalculatorResult; - fn int_divide_vec(&self, arg: &Vector) -> CalculatorResult; - fn modulo_vec(&self, arg: &Vector) -> CalculatorResult; - fn pow_vec(&self, arg: &Vector) -> CalculatorResult; - - fn add_num(&self, arg: &Number) -> CalculatorResult; - fn sub_num(&self, arg: &Number) -> CalculatorResult; - fn mul_num(&self, arg: &Number) -> CalculatorResult; - fn div_num(&self, arg: &Number) -> CalculatorResult; - fn int_divide_num(&self, arg: &Number) -> CalculatorResult; - fn modulo_num(&self, arg: &Number) -> CalculatorResult; - fn pow_num(&self, arg: &Number) -> CalculatorResult; - // Unary fn negate(&self) -> CalculatorResult; fn abs(&self) -> CalculatorResult;