Made the "Answer" struct a generic struct "Number"
This commit is contained in:
parent
d428546ecf
commit
80aacc6493
@ -1,6 +1,6 @@
|
|||||||
use decimal::d128;
|
use decimal::d128;
|
||||||
use crate::Token;
|
use crate::Token;
|
||||||
use crate::units::{Unit, UnitType};
|
use crate::units::{Unit, UnitType, Number, convert};
|
||||||
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};
|
||||||
@ -9,22 +9,7 @@ use crate::TextOperator::{To, Of};
|
|||||||
use crate::FunctionIdentifier::*;
|
use crate::FunctionIdentifier::*;
|
||||||
use crate::lookup::lookup_factorial;
|
use crate::lookup::lookup_factorial;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
pub fn evaluate(ast: &AstNode) -> Result<Number, String> {
|
||||||
pub struct Answer {
|
|
||||||
pub value: d128,
|
|
||||||
pub unit: Unit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Answer {
|
|
||||||
pub fn new(value: d128, unit: Unit) -> Answer {
|
|
||||||
Answer {
|
|
||||||
value: value,
|
|
||||||
unit: unit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn evaluate(ast: &AstNode) -> Result<Answer, String> {
|
|
||||||
let answer = evaluate_node(ast)?;
|
let answer = evaluate_node(ast)?;
|
||||||
Ok(answer)
|
Ok(answer)
|
||||||
}
|
}
|
||||||
@ -91,20 +76,20 @@ fn tan(input: d128) -> d128 {
|
|||||||
return sin(input) / cos(input);
|
return sin(input) / cos(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
||||||
let token = &ast_node.token;
|
let token = &ast_node.token;
|
||||||
let children = &ast_node.children;
|
let children = &ast_node.children;
|
||||||
match token {
|
match token {
|
||||||
Token::Number(number) => {
|
Token::Number(number) => {
|
||||||
Ok(Answer::new(number.clone(), Unit::NoUnit))
|
Ok(Number::new(number.clone(), Unit::NoUnit))
|
||||||
},
|
},
|
||||||
Token::Constant(constant) => {
|
Token::Constant(constant) => {
|
||||||
match constant {
|
match constant {
|
||||||
Pi => {
|
Pi => {
|
||||||
Ok(Answer::new(d128!(3.141592653589793238462643383279503), Unit::NoUnit))
|
Ok(Number::new(d128!(3.141592653589793238462643383279503), Unit::NoUnit))
|
||||||
},
|
},
|
||||||
E => {
|
E => {
|
||||||
Ok(Answer::new(d128!(2.718281828459045235360287471352662), Unit::NoUnit))
|
Ok(Number::new(d128!(2.718281828459045235360287471352662), Unit::NoUnit))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -115,7 +100,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Cbrt => {
|
Cbrt => {
|
||||||
if child_answer.unit.category() == UnitType::NoUnit {
|
if child_answer.unit.category() == UnitType::NoUnit {
|
||||||
let result = cbrt(child_answer.value);
|
let result = cbrt(child_answer.value);
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("log() only accepts UnitType::NoUnit").to_string())
|
return Err(format!("log() only accepts UnitType::NoUnit").to_string())
|
||||||
}
|
}
|
||||||
@ -123,7 +108,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Sqrt => {
|
Sqrt => {
|
||||||
if child_answer.unit.category() == UnitType::NoUnit {
|
if child_answer.unit.category() == UnitType::NoUnit {
|
||||||
let result = sqrt(child_answer.value);
|
let result = sqrt(child_answer.value);
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("log() only accepts UnitType::NoUnit").to_string())
|
return Err(format!("log() only accepts UnitType::NoUnit").to_string())
|
||||||
}
|
}
|
||||||
@ -131,7 +116,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Log => {
|
Log => {
|
||||||
if child_answer.unit.category() == UnitType::NoUnit {
|
if child_answer.unit.category() == UnitType::NoUnit {
|
||||||
let result = child_answer.value.log10();
|
let result = child_answer.value.log10();
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("log() only accepts UnitType::NoUnit").to_string())
|
return Err(format!("log() only accepts UnitType::NoUnit").to_string())
|
||||||
}
|
}
|
||||||
@ -139,7 +124,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Ln => {
|
Ln => {
|
||||||
if child_answer.unit.category() == UnitType::NoUnit {
|
if child_answer.unit.category() == UnitType::NoUnit {
|
||||||
let result = child_answer.value.ln();
|
let result = child_answer.value.ln();
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("ln() only accepts UnitType::NoUnit").to_string())
|
return Err(format!("ln() only accepts UnitType::NoUnit").to_string())
|
||||||
}
|
}
|
||||||
@ -147,7 +132,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Exp => {
|
Exp => {
|
||||||
if child_answer.unit.category() == UnitType::NoUnit {
|
if child_answer.unit.category() == UnitType::NoUnit {
|
||||||
let result = child_answer.value.exp(child_answer.value);
|
let result = child_answer.value.exp(child_answer.value);
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("exp() only accepts UnitType::NoUnit").to_string())
|
return Err(format!("exp() only accepts UnitType::NoUnit").to_string())
|
||||||
}
|
}
|
||||||
@ -158,49 +143,49 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
// If the result was rounded down by 0.5, correct by +1
|
// If the result was rounded down by 0.5, correct by +1
|
||||||
if rounding_change == d128!(-0.5) { result += d128!(1); }
|
if rounding_change == d128!(-0.5) { result += d128!(1); }
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
Ceil => {
|
Ceil => {
|
||||||
let mut result = child_answer.value.quantize(d128!(1));
|
let mut result = child_answer.value.quantize(d128!(1));
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
if rounding_change.is_negative() { result += d128!(1); }
|
if rounding_change.is_negative() { result += d128!(1); }
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
Floor => {
|
Floor => {
|
||||||
let mut result = child_answer.value.quantize(d128!(1));
|
let mut result = child_answer.value.quantize(d128!(1));
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
if !rounding_change.is_negative() { result -= d128!(1); }
|
if !rounding_change.is_negative() { result -= d128!(1); }
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
Abs => {
|
Abs => {
|
||||||
let mut result = child_answer.value.abs();
|
let mut result = child_answer.value.abs();
|
||||||
let rounding_change = result - child_answer.value;
|
let rounding_change = result - child_answer.value;
|
||||||
if rounding_change == d128!(-0.5) { result += d128!(1); }
|
if rounding_change == d128!(-0.5) { result += d128!(1); }
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
Sin => {
|
Sin => {
|
||||||
let result = sin(child_answer.value);
|
let result = sin(child_answer.value);
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
Cos => {
|
Cos => {
|
||||||
let result = cos(child_answer.value);
|
let result = cos(child_answer.value);
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
Tan => {
|
Tan => {
|
||||||
let result = tan(child_answer.value);
|
let result = tan(child_answer.value);
|
||||||
return Ok(Answer::new(result, child_answer.unit))
|
return Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::Unit(unit) => {
|
Token::Unit(unit) => {
|
||||||
let child_node = children.get(0).expect("Unit has no child[0]");
|
let child_node = children.get(0).expect("Unit has no child[0]");
|
||||||
let child_answer = evaluate_node(child_node)?;
|
let child_answer = evaluate_node(child_node)?;
|
||||||
Ok(Answer::new(child_answer.value, unit.clone()))
|
Ok(Number::new(child_answer.value, unit.clone()))
|
||||||
},
|
},
|
||||||
Token::Negative => {
|
Token::Negative => {
|
||||||
let child_node = children.get(0).expect("Negative has no child[0]");
|
let child_node = children.get(0).expect("Negative has no child[0]");
|
||||||
let child_answer = evaluate_node(child_node)?;
|
let child_answer = evaluate_node(child_node)?;
|
||||||
Ok(Answer::new(-child_answer.value, child_answer.unit))
|
Ok(Number::new(-child_answer.value, child_answer.unit))
|
||||||
},
|
},
|
||||||
Token::Paren => {
|
Token::Paren => {
|
||||||
let child_node = children.get(0).expect("Paren has no child[0]");
|
let child_node = children.get(0).expect("Paren has no child[0]");
|
||||||
@ -211,14 +196,14 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
let child_answer = evaluate_node(child_node)?;
|
let child_answer = evaluate_node(child_node)?;
|
||||||
match operator {
|
match operator {
|
||||||
Percent => {
|
Percent => {
|
||||||
Ok(Answer::new(child_answer.value / d128!(100), child_answer.unit))
|
Ok(Number::new(child_answer.value / d128!(100), child_answer.unit))
|
||||||
},
|
},
|
||||||
Factorial => {
|
Factorial => {
|
||||||
let result = factorial(child_answer.value);
|
let result = factorial(child_answer.value);
|
||||||
if result.is_nan() {
|
if result.is_nan() {
|
||||||
return Err("Can only perform factorial on integers from 0 to 1000".to_string());
|
return Err("Can only perform factorial on integers from 0 to 1000".to_string());
|
||||||
}
|
}
|
||||||
Ok(Answer::new(result, child_answer.unit))
|
Ok(Number::new(result, child_answer.unit))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -231,10 +216,8 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
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() {
|
if left.unit.category() == right_unit.category() {
|
||||||
let left_weight = left.unit.weight();
|
let result = convert(left, right_unit)?;
|
||||||
let right_weight = right_unit.weight();
|
return Ok(result)
|
||||||
let result = left.value * left_weight / right_weight;
|
|
||||||
return Ok(Answer::new(result, right_unit))
|
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot convert from {:?} to {:?}", left.unit, right_unit))
|
return Err(format!("Cannot convert from {:?} to {:?}", left.unit, right_unit))
|
||||||
}
|
}
|
||||||
@ -246,7 +229,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
let left = evaluate_node(left_child)?;
|
let left = evaluate_node(left_child)?;
|
||||||
let right = evaluate_node(right_child)?;
|
let right = evaluate_node(right_child)?;
|
||||||
if left.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit {
|
||||||
return Ok(Answer::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("child[0] of the Of operator must be NoUnit".to_string())
|
||||||
}
|
}
|
||||||
@ -261,20 +244,20 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
match operator {
|
match operator {
|
||||||
Plus => {
|
Plus => {
|
||||||
if left.unit == right.unit {
|
if left.unit == right.unit {
|
||||||
Ok(Answer::new(left.value + right.value, left.unit))
|
Ok(Number::new(left.value + right.value, left.unit))
|
||||||
} else if left.unit.category() == right.unit.category() {
|
} else if left.unit.category() == right.unit.category() {
|
||||||
let result = left.value * left.unit.weight() + right.value * right.unit.weight();
|
let result = left.value * left.unit.weight() + right.value * right.unit.weight();
|
||||||
Ok(Answer::new(result, Unit::Millimeter))
|
Ok(Number::new(result, Unit::Millimeter))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot add {:?} and {:?}", left.unit, right.unit))
|
return Err(format!("Cannot add {:?} and {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Minus => {
|
Minus => {
|
||||||
if left.unit == right.unit {
|
if left.unit == right.unit {
|
||||||
Ok(Answer::new(left.value - right.value, left.unit))
|
Ok(Number::new(left.value - right.value, left.unit))
|
||||||
} else if left.unit.category() == right.unit.category() {
|
} else if left.unit.category() == right.unit.category() {
|
||||||
let result = left.value * left.unit.weight() - right.value * right.unit.weight();
|
let result = left.value * left.unit.weight() - right.value * right.unit.weight();
|
||||||
Ok(Answer::new(result, Unit::Millimeter))
|
Ok(Number::new(result, Unit::Millimeter))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot subtract {:?} by {:?}", left.unit, right.unit))
|
return Err(format!("Cannot subtract {:?} by {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
@ -282,13 +265,13 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Multiply => {
|
Multiply => {
|
||||||
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
// 3 * 2
|
// 3 * 2
|
||||||
return Ok(Answer::new(left.value * right.value, left.unit))
|
return Ok(Number::new(left.value * right.value, left.unit))
|
||||||
} else if left.unit == Unit::NoUnit && right.unit != Unit::NoUnit {
|
} else if left.unit == Unit::NoUnit && right.unit != Unit::NoUnit {
|
||||||
// 3 * 1 km
|
// 3 * 1 km
|
||||||
return Ok(Answer::new(left.value * right.value, right.unit))
|
return Ok(Number::new(left.value * right.value, right.unit))
|
||||||
} else if right.unit == Unit::NoUnit && left.unit != Unit::NoUnit {
|
} else if right.unit == Unit::NoUnit && left.unit != Unit::NoUnit {
|
||||||
// 1 km * 3
|
// 1 km * 3
|
||||||
return Ok(Answer::new(left.value * right.value, left.unit))
|
return Ok(Number::new(left.value * right.value, left.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot multiply {:?} and {:?}", left.unit, right.unit))
|
return Err(format!("Cannot multiply {:?} and {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
@ -296,10 +279,10 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Divide => {
|
Divide => {
|
||||||
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
// 3 / 2
|
// 3 / 2
|
||||||
return Ok(Answer::new(left.value / right.value, left.unit))
|
return Ok(Number::new(left.value / right.value, left.unit))
|
||||||
} else if left.unit != Unit::NoUnit && right.unit == Unit::NoUnit {
|
} else if left.unit != Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
// 1 km / 2
|
// 1 km / 2
|
||||||
return Ok(Answer::new(left.value / right.value, right.unit))
|
return Ok(Number::new(left.value / right.value, right.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot divide {:?} by {:?}", left.unit, right.unit))
|
return Err(format!("Cannot divide {:?} by {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
@ -307,10 +290,10 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Modulo => {
|
Modulo => {
|
||||||
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
// 3 / 2
|
// 3 / 2
|
||||||
return Ok(Answer::new(left.value % right.value, left.unit))
|
return Ok(Number::new(left.value % right.value, left.unit))
|
||||||
} else if left.unit != Unit::NoUnit && right.unit == Unit::NoUnit {
|
} else if left.unit != Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
// 1 km / 2
|
// 1 km / 2
|
||||||
return Ok(Answer::new(left.value % right.value, right.unit))
|
return Ok(Number::new(left.value % right.value, right.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot modulo {:?} by {:?}", left.unit, right.unit))
|
return Err(format!("Cannot modulo {:?} by {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
@ -318,10 +301,10 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
|
|||||||
Caret => {
|
Caret => {
|
||||||
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
if left.unit == Unit::NoUnit && right.unit == Unit::NoUnit {
|
||||||
// 3 ^ 2
|
// 3 ^ 2
|
||||||
return Ok(Answer::new(left.value.pow(right.value), left.unit))
|
return Ok(Number::new(left.value.pow(right.value), left.unit))
|
||||||
} else if right.unit == Unit::NoUnit && left.unit != Unit::NoUnit {
|
} else if right.unit == Unit::NoUnit && left.unit != Unit::NoUnit {
|
||||||
// 1 km ^ 3
|
// 1 km ^ 3
|
||||||
return Ok(Answer::new(left.value.pow(right.value), left.unit))
|
return Ok(Number::new(left.value.pow(right.value), left.unit))
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Cannot multiply {:?} and {:?}", left.unit, right.unit))
|
return Err(format!("Cannot multiply {:?} and {:?}", left.unit, right.unit))
|
||||||
}
|
}
|
||||||
|
|||||||
60
src/units.rs
60
src/units.rs
@ -13,17 +13,17 @@ pub enum UnitType {
|
|||||||
use UnitType::*;
|
use UnitType::*;
|
||||||
|
|
||||||
macro_rules! create_units {
|
macro_rules! create_units {
|
||||||
( $( $x:ident : $y:expr ),*, ) => {
|
( $( $variant:ident : $properties:expr ),*, ) => {
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub enum Unit {
|
pub enum Unit {
|
||||||
$($x),*
|
$($variant),*
|
||||||
}
|
}
|
||||||
use Unit::*;
|
use Unit::*;
|
||||||
|
|
||||||
fn get_info(unit: &Unit) -> (UnitType, d128) {
|
fn get_info(unit: &Unit) -> (UnitType, d128) {
|
||||||
match unit {
|
match unit {
|
||||||
$(
|
$(
|
||||||
Unit::$x => $y
|
Unit::$variant => $properties
|
||||||
),*
|
),*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,27 +119,46 @@ impl Unit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Number {
|
||||||
|
pub value: d128,
|
||||||
|
pub unit: Unit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Number {
|
||||||
|
pub fn new(value: d128, unit: Unit) -> Number {
|
||||||
|
Number {
|
||||||
|
value: value,
|
||||||
|
unit: unit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_convertion_factor(unit: Unit, to_unit: Unit) -> d128 {
|
fn get_convertion_factor(unit: Unit, to_unit: Unit) -> d128 {
|
||||||
return unit.weight() / to_unit.weight();
|
return unit.weight() / to_unit.weight();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert(value: d128, unit: Unit, to_unit: Unit) -> Result<d128, String> {
|
pub fn convert(number: Number, to_unit: Unit) -> Result<Number, String> {
|
||||||
if unit.category() == UnitType::Temperature {
|
let value = number.value;
|
||||||
match (unit, to_unit) {
|
let ok = |new_value| {
|
||||||
(Kelvin, Kelvin) => Ok(value),
|
Ok(Number::new(new_value, to_unit))
|
||||||
(Kelvin, Celcius) => Ok(value-d128!(273.15)),
|
};
|
||||||
(Kelvin, Fahrenheit) => Ok(value*d128!(1.8)-d128!(459.67)),
|
if number.unit.category() == UnitType::Temperature {
|
||||||
(Celcius, Celcius) => Ok(value),
|
match (number.unit, to_unit) {
|
||||||
(Celcius, Kelvin) => Ok(value+d128!(273.15)),
|
(Kelvin, Kelvin) => ok(value),
|
||||||
(Celcius, Fahrenheit) => Ok(value*d128!(1.8)+d128!(32)),
|
(Kelvin, Celcius) => ok(value-d128!(273.15)),
|
||||||
(Fahrenheit, Fahrenheit) => Ok(value),
|
(Kelvin, Fahrenheit) => ok(value*d128!(1.8)-d128!(459.67)),
|
||||||
(Fahrenheit, Kelvin) => Ok((value+d128!(459.67))*d128!(5)/d128!(9)),
|
(Celcius, Celcius) => ok(value),
|
||||||
(Fahrenheit, Celcius) => Ok((value-d128!(32))/d128!(1.8)),
|
(Celcius, Kelvin) => ok(value+d128!(273.15)),
|
||||||
_ => Err(format!("Error converting temperature {:?} to {:?}", unit, to_unit)),
|
(Celcius, Fahrenheit) => ok(value*d128!(1.8)+d128!(32)),
|
||||||
|
(Fahrenheit, Fahrenheit) => ok(value),
|
||||||
|
(Fahrenheit, Kelvin) => ok((value+d128!(459.67))*d128!(5)/d128!(9)),
|
||||||
|
(Fahrenheit, Celcius) => ok((value-d128!(32))/d128!(1.8)),
|
||||||
|
_ => Err(format!("Error converting temperature {:?} to {:?}", number.unit, to_unit)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let convertion_factor = get_convertion_factor(unit, to_unit);
|
let convertion_factor = get_convertion_factor(number.unit, to_unit);
|
||||||
Ok(value * convertion_factor)
|
ok(number.value * convertion_factor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,9 +173,10 @@ mod tests {
|
|||||||
|
|
||||||
let value_string = &value.to_string();
|
let value_string = &value.to_string();
|
||||||
let value_d128 = d128::from_str(value_string).unwrap();
|
let value_d128 = d128::from_str(value_string).unwrap();
|
||||||
|
let number = Number::new(value_d128, unit);
|
||||||
|
|
||||||
let result = convert(value_d128, unit, to_unit);
|
let result = convert(number, to_unit);
|
||||||
let string_result = &result.unwrap().to_string();
|
let string_result = &result.unwrap().value.to_string();
|
||||||
let float_result = f64::from_str(string_result).unwrap();
|
let float_result = f64::from_str(string_result).unwrap();
|
||||||
|
|
||||||
return float_result;
|
return float_result;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user