From c6ea10c1af50cee26e6bdf97f78b30a441f33bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konsta=20H=C3=B6ltt=C3=A4?= Date: Wed, 22 Jul 2020 23:00:28 +0300 Subject: [PATCH] return null for first, last, nth on error Instead of empty string, return null value that's considered undefined (and can be piped to the default filter) if the array is empty for the filters first, last and nth. For nth, also change the out-of-bounds value from empty string to null. Closes #534, and is a breaking change. --- docs/content/docs/_index.md | 8 ++++---- src/builtins/filters/array.rs | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/content/docs/_index.md b/docs/content/docs/_index.md index 1dae41cdc..22cd6dae8 100644 --- a/docs/content/docs/_index.md +++ b/docs/content/docs/_index.md @@ -819,15 +819,15 @@ before `striptags`. #### first Returns the first element of an array. -If the array is empty, returns empty string. +If the array is empty, returns null (undefined) that can be chained to the default filter. #### last Returns the last element of an array. -If the array is empty, returns empty string. +If the array is empty, returns null (undefined) that can be chained to the default filter. #### nth -Returns the nth element of an array.ยง -If the array is empty, returns empty string. +Returns the nth element of an array. +If the array is empty or if the nth is out of bounds, returns null (undefined) that can be chained to the default filter. It takes a required `n` argument, corresponding to the 0-based index you want to get. Example: `{{ value | nth(n=2) }}` diff --git a/src/builtins/filters/array.rs b/src/builtins/filters/array.rs index a13e62ad4..b3e68bec3 100644 --- a/src/builtins/filters/array.rs +++ b/src/builtins/filters/array.rs @@ -7,12 +7,12 @@ use crate::filter_utils::{get_sort_strategy_for_type, get_unique_strategy_for_ty use serde_json::value::{to_value, Map, Value}; /// Returns the nth value of an array -/// If the array is empty, returns empty string +/// If the array is empty, returns null pub fn nth(value: &Value, args: &HashMap) -> Result { let arr = try_get_value!("nth", "value", Vec, value); if arr.is_empty() { - return Ok(to_value("").unwrap()); + return Ok(Value::Null); } let index = match args.get("n") { @@ -20,32 +20,32 @@ pub fn nth(value: &Value, args: &HashMap) -> Result { None => return Err(Error::msg("The `nth` filter has to have an `n` argument")), }; - Ok(arr.get(index).unwrap_or(&to_value("").unwrap()).to_owned()) + Ok(arr.get(index).map(|x| x.to_owned()).unwrap_or(Value::Null)) } /// Returns the first value of an array -/// If the array is empty, returns empty string +/// If the array is empty, returns null pub fn first(value: &Value, _: &HashMap) -> Result { let mut arr = try_get_value!("first", "value", Vec, value); if arr.is_empty() { - Ok(to_value("").unwrap()) + Ok(Value::Null) } else { Ok(arr.swap_remove(0)) } } /// Returns the last value of an array -/// If the array is empty, returns empty string +/// If the array is empty, returns null pub fn last(value: &Value, _: &HashMap) -> Result { let mut arr = try_get_value!("last", "value", Vec, value); - Ok(arr.pop().unwrap_or_else(|| to_value("").unwrap())) + Ok(arr.pop().unwrap_or(Value::Null)) } /// Joins all values in the array by the `sep` argument given /// If no separator is given, it will use `""` (empty string) as separator -/// If the array is empty, returns empty string +/// If the array is empty, returns null pub fn join(value: &Value, args: &HashMap) -> Result { let arr = try_get_value!("join", "value", Vec, value); let sep = match args.get("sep") { @@ -319,7 +319,7 @@ mod tests { args.insert("n".to_string(), to_value(1).unwrap()); let result = nth(&to_value(&v).unwrap(), &args); assert!(result.is_ok()); - assert_eq!(result.unwrap(), to_value("").unwrap()); + assert_eq!(result.unwrap(), Value::Null); } #[test] @@ -335,7 +335,7 @@ mod tests { let result = first(&to_value(&v).unwrap(), &HashMap::new()); assert!(result.is_ok()); - assert_eq!(result.ok().unwrap(), to_value("").unwrap()); + assert_eq!(result.ok().unwrap(), Value::Null); } #[test] @@ -351,7 +351,7 @@ mod tests { let result = last(&to_value(&v).unwrap(), &HashMap::new()); assert!(result.is_ok()); - assert_eq!(result.ok().unwrap(), to_value("").unwrap()); + assert_eq!(result.ok().unwrap(), Value::Null); } #[test]