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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander