diff --git a/src/bin.rs b/src/bin.rs index e282473..d0695ce 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -5,13 +5,13 @@ use parser::Filter; use parser::OwnedLiteral; use parser::Template; use renderer::compile_template; -use renderer::math_ints; use renderer::CompileError; use renderer::ContextElement; use renderer::DustRenderer; use renderer::IceResult; use renderer::IntoContextElement; use renderer::Loopable; +use renderer::MathNumber; use renderer::RenderError; use renderer::Renderable; use renderer::Truthiness; @@ -22,7 +22,6 @@ use std::convert::TryInto; use std::env; use std::fs; use std::io::{self, Read}; -use std::ops::Add; use std::path::Path; mod parser; @@ -561,13 +560,6 @@ where } } -#[derive(Debug)] -enum MathNumber { - Integer(i128), - Decimal(f64), - Failure, -} - impl From<&serde_json::Value> for MathNumber { fn from(original: &serde_json::Value) -> Self { match original { @@ -611,41 +603,6 @@ impl From<&serde_json::Number> for MathNumber { } } -impl From<&OwnedLiteral> for MathNumber { - fn from(original: &OwnedLiteral) -> Self { - match original { - OwnedLiteral::LString(_) => panic!("Strings should not be cast to numbers for math"), - OwnedLiteral::LPositiveInteger(num) => { - return MathNumber::Integer((*num).try_into().unwrap()) - } - OwnedLiteral::LNegativeInteger(num) => return MathNumber::Integer((*num).into()), - OwnedLiteral::LFloat(num) => return MathNumber::Decimal(*num), - } - } -} - -impl Add for MathNumber { - type Output = Option; - - fn add(self, other: MathNumber) -> Self::Output { - match (self, other) { - (MathNumber::Failure, _) | (_, MathNumber::Failure) => None, - (MathNumber::Integer(self_num), MathNumber::Integer(other_num)) => { - math_ints(self_num, other_num, std::ops::Add::add) - } - (MathNumber::Decimal(self_num), MathNumber::Decimal(other_num)) => { - Some(OwnedLiteral::LFloat(self_num + other_num)) - } - (MathNumber::Integer(self_num), MathNumber::Decimal(other_num)) => { - Some(OwnedLiteral::LFloat((self_num as f64) + other_num)) - } - (MathNumber::Decimal(self_num), MathNumber::Integer(other_num)) => { - Some(OwnedLiteral::LFloat(self_num + (other_num as f64))) - } - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/renderer/math.rs b/src/renderer/math.rs new file mode 100644 index 0000000..02b305e --- /dev/null +++ b/src/renderer/math.rs @@ -0,0 +1,76 @@ +use crate::parser::OwnedLiteral; +use std::convert::TryInto; +use std::ops::Add; + +#[derive(Debug)] +pub enum MathNumber { + Integer(i128), + Decimal(f64), + Failure, +} + +impl From<&OwnedLiteral> for MathNumber { + fn from(original: &OwnedLiteral) -> Self { + match original { + OwnedLiteral::LString(_) => panic!("Strings should not be cast to numbers for math"), + OwnedLiteral::LPositiveInteger(num) => { + return MathNumber::Integer((*num).try_into().unwrap()) + } + OwnedLiteral::LNegativeInteger(num) => return MathNumber::Integer((*num).into()), + OwnedLiteral::LFloat(num) => return MathNumber::Decimal(*num), + } + } +} + +impl Add for MathNumber { + type Output = Option; + + fn add(self, other: MathNumber) -> Self::Output { + match (self, other) { + (MathNumber::Failure, _) | (_, MathNumber::Failure) => None, + (MathNumber::Integer(self_num), MathNumber::Integer(other_num)) => { + math_ints(self_num, other_num, std::ops::Add::add) + } + (MathNumber::Decimal(self_num), MathNumber::Decimal(other_num)) => { + Some(OwnedLiteral::LFloat(self_num + other_num)) + } + (MathNumber::Integer(self_num), MathNumber::Decimal(other_num)) => { + Some(OwnedLiteral::LFloat((self_num as f64) + other_num)) + } + (MathNumber::Decimal(self_num), MathNumber::Integer(other_num)) => { + Some(OwnedLiteral::LFloat(self_num + (other_num as f64))) + } + } + } +} + +/// For math operations that take in integers and return integers +/// (add, subtract, multiply) +pub fn math_ints(left: L, right: R, operation: F) -> Option +where + L: Into, + R: Into, + F: Fn(i128, i128) -> i128, +{ + let result = operation(left.into(), right.into()); + std::convert::TryInto::::try_into(result) + .map(OwnedLiteral::LPositiveInteger) + .ok() + .or(std::convert::TryInto::::try_into(result) + .map(OwnedLiteral::LNegativeInteger) + .ok()) +} + +// /// For math operations that take in integers and return integers +// /// (add, subtract, multiply) +// fn math_floats(left: L, right: R, operation: F) -> Option +// where +// L: Into, +// R: Into, +// F: Fn(f64, f64) -> f64, +// { +// let result = operation(left.into(), right.into()); +// std::convert::TryInto::::try_into(result) +// .map(OwnedLiteral::LFloat) +// .ok() +// } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index f773381..cf5ec08 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -5,6 +5,7 @@ mod context_element; mod errors; mod inline_partial_tree; mod iteration_context; +mod math; mod parameters_context; mod renderer; mod select_context; @@ -21,7 +22,7 @@ pub use context_element::Walkable; pub use errors::CompileError; pub use errors::RenderError; pub use errors::WalkError; -pub use parameters_context::math_ints; +pub use math::MathNumber; pub use renderer::compile_template; pub use renderer::DustRenderer; pub use select_context::SelectContext; diff --git a/src/renderer/parameters_context.rs b/src/renderer/parameters_context.rs index 85a422d..23b720d 100644 --- a/src/renderer/parameters_context.rs +++ b/src/renderer/parameters_context.rs @@ -7,6 +7,7 @@ use crate::renderer::context_element::CompareContextElement; use crate::renderer::context_element::ContextElement; use crate::renderer::context_element::IceResult; use crate::renderer::context_element::IntoContextElement; +use crate::renderer::math::MathNumber; use crate::renderer::walking::walk_path; use crate::renderer::DustRenderer; use crate::renderer::Loopable; @@ -18,7 +19,6 @@ use crate::renderer::Walkable; use std::borrow::Borrow; use std::cmp::Ordering; use std::collections::HashMap; -use std::convert::TryInto; #[derive(Debug)] pub struct ParametersContext<'a> { @@ -334,85 +334,12 @@ impl CompareContextElement for OwnedLiteral { // type. match other.to_any().downcast_ref::() { None => other.math_add(self), - Some(other_literal) => { - match (self, other_literal) { - (OwnedLiteral::LString(_), _) | (_, OwnedLiteral::LString(_)) => None, - ( - OwnedLiteral::LPositiveInteger(self_num), - OwnedLiteral::LPositiveInteger(other_num), - ) => math_ints(*self_num, *other_num, std::ops::Add::add) - .map(IceResult::from_owned), - ( - OwnedLiteral::LNegativeInteger(self_num), - OwnedLiteral::LNegativeInteger(other_num), - ) => math_ints(*self_num, *other_num, std::ops::Add::add) - .map(IceResult::from_owned), - ( - OwnedLiteral::LPositiveInteger(self_num), - OwnedLiteral::LNegativeInteger(other_num), - ) => math_ints(*self_num, *other_num, std::ops::Add::add) - .map(IceResult::from_owned), - ( - OwnedLiteral::LNegativeInteger(self_num), - OwnedLiteral::LPositiveInteger(other_num), - ) => math_ints(*self_num, *other_num, std::ops::Add::add) - .map(IceResult::from_owned), - (OwnedLiteral::LFloat(self_num), OwnedLiteral::LFloat(other_num)) => Some( - IceResult::from_owned(OwnedLiteral::LFloat(self_num + other_num)), - ), - (OwnedLiteral::LFloat(self_num), OwnedLiteral::LPositiveInteger(other_num)) => { - Some(IceResult::from_owned(OwnedLiteral::LFloat( - self_num + (*other_num as f64), - ))) - } - (OwnedLiteral::LPositiveInteger(self_num), OwnedLiteral::LFloat(other_num)) => { - Some(IceResult::from_owned(OwnedLiteral::LFloat( - (*self_num as f64) + other_num, - ))) - } - (OwnedLiteral::LFloat(self_num), OwnedLiteral::LNegativeInteger(other_num)) => { - Some(IceResult::from_owned(OwnedLiteral::LFloat( - self_num + (*other_num as f64), - ))) - } - (OwnedLiteral::LNegativeInteger(self_num), OwnedLiteral::LFloat(other_num)) => { - Some(IceResult::from_owned(OwnedLiteral::LFloat( - (*self_num as f64) + other_num, - ))) - } - } - } + Some(other_literal) => match (self, other_literal) { + (OwnedLiteral::LString(_), _) | (_, OwnedLiteral::LString(_)) => None, + (_, _) => (std::convert::Into::::into(self) + + std::convert::Into::::into(other_literal)) + .map(IceResult::from_owned), + }, } } } - -/// For math operations that take in integers and return integers -/// (add, subtract, multiply) -pub fn math_ints(left: L, right: R, operation: F) -> Option -where - L: Into, - R: Into, - F: Fn(i128, i128) -> i128, -{ - let result = operation(left.into(), right.into()); - std::convert::TryInto::::try_into(result) - .map(OwnedLiteral::LPositiveInteger) - .ok() - .or(std::convert::TryInto::::try_into(result) - .map(OwnedLiteral::LNegativeInteger) - .ok()) -} - -// /// For math operations that take in integers and return integers -// /// (add, subtract, multiply) -// fn math_floats(left: L, right: R, operation: F) -> Option -// where -// L: Into, -// R: Into, -// F: Fn(f64, f64) -> f64, -// { -// let result = operation(left.into(), right.into()); -// std::convert::TryInto::::try_into(result) -// .map(OwnedLiteral::LFloat) -// .ok() -// }