Moved addition/subtraction to units.rs
This commit is contained in:
parent
adaf4eb4ac
commit
eb8c1a0a37
@ -1,6 +1,6 @@
|
|||||||
use decimal::d128;
|
use decimal::d128;
|
||||||
use crate::Token;
|
use crate::Token;
|
||||||
use crate::units::{Unit, UnitType, Number, convert};
|
use crate::units::{Unit, UnitType, Number, convert, add, subtract};
|
||||||
use crate::parser::AstNode;
|
use crate::parser::AstNode;
|
||||||
use crate::Operator::{Caret, Divide, Minus, Modulo, Multiply, Plus};
|
use crate::Operator::{Caret, Divide, Minus, Modulo, Multiply, Plus};
|
||||||
use crate::Constant::{Pi, E};
|
use crate::Constant::{Pi, E};
|
||||||
@ -215,12 +215,8 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
To => {
|
To => {
|
||||||
if let Token::Unit(right_unit) = right_child.token {
|
if let Token::Unit(right_unit) = right_child.token {
|
||||||
let left = evaluate_node(left_child)?;
|
let left = evaluate_node(left_child)?;
|
||||||
if left.unit.category() == right_unit.category() {
|
|
||||||
let result = convert(left, right_unit)?;
|
let result = convert(left, right_unit)?;
|
||||||
return Ok(result)
|
return Ok(result)
|
||||||
} else {
|
|
||||||
return Err(format!("Cannot convert from {:?} to {:?}", left.unit, right_unit))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Err("Right side of To operator needs to be a unit".to_string())
|
return Err("Right side of To operator needs to be a unit".to_string())
|
||||||
}
|
}
|
||||||
@ -231,7 +227,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
if left.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit {
|
||||||
return Ok(Number::new(left.value * right.value, right.unit))
|
return Ok(Number::new(left.value * right.value, right.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err("child[0] of the Of operator must be NoUnit".to_string())
|
return Err("Left side of the Of operator must be NoUnit".to_string())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -243,24 +239,10 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
let right = evaluate_node(right_child)?;
|
let right = evaluate_node(right_child)?;
|
||||||
match operator {
|
match operator {
|
||||||
Plus => {
|
Plus => {
|
||||||
if left.unit == right.unit {
|
Ok(add(left, right)?)
|
||||||
Ok(Number::new(left.value + right.value, left.unit))
|
|
||||||
} else if left.unit.category() == right.unit.category() {
|
|
||||||
let result = left.value * left.unit.weight() + right.value * right.unit.weight();
|
|
||||||
Ok(Number::new(result, Unit::Millimeter))
|
|
||||||
} else {
|
|
||||||
return Err(format!("Cannot add {:?} and {:?}", left.unit, right.unit))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Minus => {
|
Minus => {
|
||||||
if left.unit == right.unit {
|
Ok(subtract(left, right)?)
|
||||||
Ok(Number::new(left.value - right.value, left.unit))
|
|
||||||
} else if left.unit.category() == right.unit.category() {
|
|
||||||
let result = left.value * left.unit.weight() - right.value * right.unit.weight();
|
|
||||||
Ok(Number::new(result, Unit::Millimeter))
|
|
||||||
} else {
|
|
||||||
return Err(format!("Cannot subtract {:?} by {:?}", left.unit, right.unit))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Multiply => {
|
Multiply => {
|
||||||
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
|
|||||||
35
src/units.rs
35
src/units.rs
@ -228,6 +228,9 @@ fn get_convertion_factor(unit: Unit, to_unit: Unit) -> d128 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
||||||
|
if number.unit.category() != to_unit.category() {
|
||||||
|
return Err(format!("Cannot convert from {:?} to {:?}", number.unit, to_unit));
|
||||||
|
}
|
||||||
let value = number.value;
|
let value = number.value;
|
||||||
let ok = |new_value| {
|
let ok = |new_value| {
|
||||||
Ok(Number::new(new_value, to_unit))
|
Ok(Number::new(new_value, to_unit))
|
||||||
@ -251,6 +254,38 @@ pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add(left: Number, right: Number) -> Result<Number, String> {
|
||||||
|
if left.unit == right.unit {
|
||||||
|
Ok(Number::new(left.value + right.value, left.unit))
|
||||||
|
} else if left.unit.category() == right.unit.category() && left.unit.category() != Temperature {
|
||||||
|
if left.unit.weight() > right.unit.weight() {
|
||||||
|
let left_converted = convert(left, right.unit)?;
|
||||||
|
Ok(Number::new(left_converted.value + right.value, right.unit))
|
||||||
|
} else {
|
||||||
|
let right_converted = convert(right, left.unit)?;
|
||||||
|
Ok(Number::new(right_converted.value + left.value, left.unit))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(format!("Cannot add {:?} and {:?}", left.unit, right.unit))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subtract(left: Number, right: Number) -> Result<Number, String> {
|
||||||
|
if left.unit == right.unit {
|
||||||
|
Ok(Number::new(left.value - right.value, left.unit))
|
||||||
|
} else if left.unit.category() == right.unit.category() && left.unit.category() != Temperature {
|
||||||
|
if left.unit.weight() > right.unit.weight() {
|
||||||
|
let left_converted = convert(left, right.unit)?;
|
||||||
|
Ok(Number::new(left_converted.value - right.value, right.unit))
|
||||||
|
} else {
|
||||||
|
let right_converted = convert(right, left.unit)?;
|
||||||
|
Ok(Number::new(right_converted.value - left.value, left.unit))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(format!("Cannot subtract {:?} by {:?}", left.unit, right.unit))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user