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