Wire up serde_json for the math functions.

This commit is contained in:
Tom Alexander 2020-06-13 22:55:38 -04:00
parent 431b34dac7
commit cdd10576e8
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 103 additions and 9 deletions

View File

@ -441,31 +441,125 @@ impl CompareContextElement for serde_json::Value {
}
fn math_subtract<'a>(&self, other: &dyn ContextElement) -> Option<IceResult<'a>> {
todo!()
let other_json = other.to_any().downcast_ref::<Self>();
let other_literal = other.to_any().downcast_ref::<OwnedLiteral>();
match (self, other_json, other_literal) {
// 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
(_, Some(other_json_value), _) => (std::convert::Into::<MathNumber>::into(self)
- std::convert::Into::<MathNumber>::into(other_json_value))
.map(IceResult::from_owned),
// Handle literals
(_, _, Some(other_literal)) => (std::convert::Into::<MathNumber>::into(self)
- std::convert::Into::<MathNumber>::into(other_literal))
.map(IceResult::from_owned),
}
}
fn math_multiply<'a>(&self, other: &dyn ContextElement) -> Option<IceResult<'a>> {
todo!()
let other_json = other.to_any().downcast_ref::<Self>();
let other_literal = other.to_any().downcast_ref::<OwnedLiteral>();
match (self, other_json, other_literal) {
// 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
(_, Some(other_json_value), _) => (std::convert::Into::<MathNumber>::into(self)
* std::convert::Into::<MathNumber>::into(other_json_value))
.map(IceResult::from_owned),
// Handle literals
(_, _, Some(other_literal)) => (std::convert::Into::<MathNumber>::into(self)
* std::convert::Into::<MathNumber>::into(other_literal))
.map(IceResult::from_owned),
}
}
fn math_divide<'a>(&self, other: &dyn ContextElement) -> Option<IceResult<'a>> {
todo!()
let other_json = other.to_any().downcast_ref::<Self>();
let other_literal = other.to_any().downcast_ref::<OwnedLiteral>();
match (self, other_json, other_literal) {
// 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
(_, Some(other_json_value), _) => (std::convert::Into::<MathNumber>::into(self)
/ std::convert::Into::<MathNumber>::into(other_json_value))
.map(IceResult::from_owned),
// Handle literals
(_, _, Some(other_literal)) => (std::convert::Into::<MathNumber>::into(self)
/ std::convert::Into::<MathNumber>::into(other_literal))
.map(IceResult::from_owned),
}
}
fn math_modulus<'a>(&self, other: &dyn ContextElement) -> Option<IceResult<'a>> {
todo!()
let other_json = other.to_any().downcast_ref::<Self>();
let other_literal = other.to_any().downcast_ref::<OwnedLiteral>();
match (self, other_json, other_literal) {
// 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
(_, Some(other_json_value), _) => (std::convert::Into::<MathNumber>::into(self)
% std::convert::Into::<MathNumber>::into(other_json_value))
.map(IceResult::from_owned),
// Handle literals
(_, _, Some(other_literal)) => (std::convert::Into::<MathNumber>::into(self)
% std::convert::Into::<MathNumber>::into(other_literal))
.map(IceResult::from_owned),
}
}
fn math_abs<'a>(&self) -> Option<IceResult<'a>> {
todo!()
std::convert::Into::<MathNumber>::into(self)
.math_abs()
.map(IceResult::from_owned)
}
fn math_floor<'a>(&self) -> Option<IceResult<'a>> {
todo!()
std::convert::Into::<MathNumber>::into(self)
.math_floor()
.map(IceResult::from_owned)
}
fn math_ceil<'a>(&self) -> Option<IceResult<'a>> {
todo!()
std::convert::Into::<MathNumber>::into(self)
.math_ceil()
.map(IceResult::from_owned)
}
}
@ -630,7 +724,7 @@ impl From<&serde_json::Value> for MathNumber {
}
}
serde_json::Value::Number(num) => num.into(),
serde_json::Value::String(text) => {
serde_json::Value::String(_) => {
panic!("Strings should not be cast to numbers for math")
}
serde_json::Value::Array(_) => {

View File

@ -233,7 +233,7 @@ impl CompareContextElement for OwnedLiteral {
OwnedLiteral::LNegativeInteger(self_num),
OwnedLiteral::LNegativeInteger(other_num),
) => self_num == other_num,
(OwnedLiteral::LString(self_text), _) | (_, OwnedLiteral::LString(self_text)) => {
(OwnedLiteral::LString(_self_text), _) | (_, OwnedLiteral::LString(_self_text)) => {
false
}
(OwnedLiteral::LFloat(self_num), OwnedLiteral::LFloat(other_num)) => {