Add an is_castable() function to stop casting to number for booleans in the @size helper.
This commit is contained in:
		
							parent
							
								
									e54e20d254
								
							
						
					
					
						commit
						a622a7e1bc
					
				
							
								
								
									
										13
									
								
								src/bin.rs
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/bin.rs
									
									
									
									
									
								
							| @ -317,6 +317,17 @@ impl Loopable for serde_json::Value { | ||||
| } | ||||
| 
 | ||||
| impl Sizable for serde_json::Value { | ||||
|     fn is_castable(&self) -> bool { | ||||
|         match self { | ||||
|             serde_json::Value::Null => true, | ||||
|             serde_json::Value::Bool(_) => false, | ||||
|             serde_json::Value::Number(_) => true, | ||||
|             serde_json::Value::String(_) => true, | ||||
|             serde_json::Value::Array(_) => true, | ||||
|             serde_json::Value::Object(_) => true, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn get_size<'a>(&'a self) -> Option<IceResult<'a>> { | ||||
|         match self { | ||||
|             serde_json::Value::Null => { | ||||
| @ -368,7 +379,7 @@ impl Castable for serde_json::Value { | ||||
|             (serde_json::Value::Array(_), "number") => None, | ||||
|             (serde_json::Value::Object(_), "number") => None, | ||||
| 
 | ||||
|             (serde_json::Value::String(text), "string") => Some(IceResult::from_borrowed(self)), | ||||
|             (serde_json::Value::String(_), "string") => Some(IceResult::from_borrowed(self)), | ||||
|             (serde_json::Value::Number(num), "string") => Some(IceResult::from_owned( | ||||
|                 serde_json::Value::String(num.to_string()), | ||||
|             )), | ||||
|  | ||||
| @ -65,6 +65,18 @@ pub trait Castable { | ||||
| } | ||||
| 
 | ||||
| pub trait Sizable { | ||||
|     /// Special case: In DustJS the @size helper usually attempts to
 | ||||
|     /// cast to a number before calculating the size. The exception to
 | ||||
|     /// this is booleans. `Number(true) == 1` but `@size` on any
 | ||||
|     /// boolean is always 0. Make this function return false for any
 | ||||
|     /// type that casting to a number shouldn't be attempted.
 | ||||
|     ///
 | ||||
|     /// Note: Its fine for objects that cannot be cast to a number to
 | ||||
|     /// return true here. False is only needed for cases where casting
 | ||||
|     /// to a number would cause a deviation in the final value for
 | ||||
|     /// `@size`.
 | ||||
|     fn is_castable(&self) -> bool; | ||||
| 
 | ||||
|     fn get_size<'a>(&'a self) -> Option<IceResult<'a>>; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -196,6 +196,16 @@ impl Walkable for OwnedLiteral { | ||||
| } | ||||
| 
 | ||||
| impl Sizable for OwnedLiteral { | ||||
|     fn is_castable(&self) -> bool { | ||||
|         match self { | ||||
|             OwnedLiteral::LBoolean(_) => false, | ||||
|             OwnedLiteral::LFloat(_) => true, | ||||
|             OwnedLiteral::LPositiveInteger(_) => true, | ||||
|             OwnedLiteral::LNegativeInteger(_) => true, | ||||
|             OwnedLiteral::LString(_) => true, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn get_size<'a>(&'a self) -> Option<IceResult<'a>> { | ||||
|         match self { | ||||
|             OwnedLiteral::LBoolean(_) => { | ||||
|  | ||||
| @ -730,7 +730,6 @@ impl<'a> DustRenderer<'a> { | ||||
|                     maybe_ice | ||||
|                         .as_ref() | ||||
|                         .map(|ice| ice.get_context_element_reference()) | ||||
|                     // .map(|ce| ce.get_size())
 | ||||
|                 }); | ||||
|                 match value_ce { | ||||
|                     // If "key" is not on the @size tag at all, render 0.
 | ||||
| @ -742,8 +741,8 @@ impl<'a> DustRenderer<'a> { | ||||
|                         // numbers, and if that succeeds it uses the
 | ||||
|                         // number, otherwise we'll get the size of the
 | ||||
|                         // original type.
 | ||||
|                         match ce.cast_to_type("number") { | ||||
|                             Some(ice) => { | ||||
|                         match (ce.cast_to_type("number"), ce.is_castable()) { | ||||
|                             (Some(ice), true) => { | ||||
|                                 return ice | ||||
|                                     .get_context_element_reference() | ||||
|                                     .get_size() | ||||
| @ -752,7 +751,15 @@ impl<'a> DustRenderer<'a> { | ||||
|                                     }) | ||||
|                                     .unwrap_or(Ok("".to_owned())) | ||||
|                             } | ||||
|                             None => { | ||||
|                             (Some(_), false) => { | ||||
|                                 return ce | ||||
|                                     .get_size() | ||||
|                                     .map(|ce_size| { | ||||
|                                         ce_size.get_context_element_reference().render(&Vec::new()) | ||||
|                                     }) | ||||
|                                     .unwrap_or(Ok("".to_owned())) | ||||
|                             } | ||||
|                             (None, _) => { | ||||
|                                 return ce | ||||
|                                     .get_size() | ||||
|                                     .map(|ce_size| { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander