Start of implementation for serde_json but I'm going to change my approach.
The permutations are pretty intense, so I think I'm going to do the same design I did for comparison where I have a JsonNumber (but I'll call this one MathNumber and rename JsonNumber to ComparisonNumber), convert the types to that, and then do the math.
This commit is contained in:
parent
db11677b22
commit
df0ae05648
59
src/bin.rs
59
src/bin.rs
@ -5,6 +5,7 @@ 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;
|
||||
@ -390,7 +391,63 @@ impl CompareContextElement for serde_json::Value {
|
||||
}
|
||||
|
||||
fn math_add<'a>(&self, other: &dyn ContextElement) -> Option<IceResult<'a>> {
|
||||
todo!()
|
||||
match (
|
||||
self,
|
||||
other.to_any().downcast_ref::<Self>(),
|
||||
other.to_any().downcast_ref::<OwnedLiteral>(),
|
||||
) {
|
||||
// If its neither of those types, then it is unimplemented
|
||||
(_, None, None) => panic!("Math operation on unimplemented type"),
|
||||
// Since this is specifically for the math helper, non-primitives are not supported
|
||||
(serde_json::Value::Array(_), _, _)
|
||||
| (serde_json::Value::Object(_), _, _)
|
||||
| (_, Some(serde_json::Value::Array(_)), _)
|
||||
| (_, Some(serde_json::Value::Object(_)), _) => None,
|
||||
// Strings also are ignored because this is specifically a math function
|
||||
(serde_json::Value::String(_), _, _)
|
||||
| (_, Some(serde_json::Value::String(_)), _)
|
||||
| (_, _, Some(OwnedLiteral::LString(_))) => None,
|
||||
// Handle other serde_json::Value
|
||||
(
|
||||
serde_json::Value::Number(self_num),
|
||||
Some(serde_json::Value::Number(other_num)),
|
||||
_,
|
||||
) => {
|
||||
match (
|
||||
self_num.as_u64(),
|
||||
other_num.as_u64(),
|
||||
self_num.as_i64(),
|
||||
other_num.as_i64(),
|
||||
self_num.as_f64(),
|
||||
other_num.as_f64(),
|
||||
) {
|
||||
// If both numbers are integers, we can pass them into math_ints
|
||||
(Some(self_num), Some(other_num), _, _, _, _) => {
|
||||
math_ints(self_num, other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned)
|
||||
}
|
||||
(_, _, Some(self_num), Some(other_num), _, _) => {
|
||||
math_ints(self_num, other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned)
|
||||
}
|
||||
(Some(self_num), _, _, Some(other_num), _, _) => {
|
||||
math_ints(self_num, other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned)
|
||||
}
|
||||
(_, Some(other_num), Some(self_num), _, _, _) => {
|
||||
math_ints(self_num, other_num, std::ops::Add::add)
|
||||
.map(IceResult::from_owned)
|
||||
}
|
||||
// Otherwise they'll be floats and we can just do the math directly
|
||||
(_, _, _, _, Some(self_num), Some(other_num)) => Some(IceResult::from_owned(
|
||||
OwnedLiteral::LFloat(self_num + other_num),
|
||||
)),
|
||||
_ => panic!("Unhandled operation, some integer must not have cast to a float."),
|
||||
}
|
||||
}
|
||||
// Handle literals
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,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 renderer::compile_template;
|
||||
pub use renderer::DustRenderer;
|
||||
pub use select_context::SelectContext;
|
||||
|
@ -388,7 +388,7 @@ impl CompareContextElement for OwnedLiteral {
|
||||
|
||||
/// For math operations that take in integers and return integers
|
||||
/// (add, subtract, multiply)
|
||||
fn math_ints<L, R, F>(left: L, right: R, operation: F) -> Option<OwnedLiteral>
|
||||
pub fn math_ints<L, R, F>(left: L, right: R, operation: F) -> Option<OwnedLiteral>
|
||||
where
|
||||
L: Into<i128>,
|
||||
R: Into<i128>,
|
||||
|
Loading…
Reference in New Issue
Block a user