Skip to content

Commit c6ea10c

Browse files
committed
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 Keats#534, and is a breaking change.
1 parent 5dc12af commit c6ea10c

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

docs/content/docs/_index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -819,15 +819,15 @@ before `striptags`.
819819

820820
#### first
821821
Returns the first element of an array.
822-
If the array is empty, returns empty string.
822+
If the array is empty, returns null (undefined) that can be chained to the default filter.
823823

824824
#### last
825825
Returns the last element of an array.
826-
If the array is empty, returns empty string.
826+
If the array is empty, returns null (undefined) that can be chained to the default filter.
827827

828828
#### nth
829-
Returns the nth element of an array.§
830-
If the array is empty, returns empty string.
829+
Returns the nth element of an array.
830+
If the array is empty or if the nth is out of bounds, returns null (undefined) that can be chained to the default filter.
831831
It takes a required `n` argument, corresponding to the 0-based index you want to get.
832832

833833
Example: `{{ value | nth(n=2) }}`

src/builtins/filters/array.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,45 @@ use crate::filter_utils::{get_sort_strategy_for_type, get_unique_strategy_for_ty
77
use serde_json::value::{to_value, Map, Value};
88

99
/// Returns the nth value of an array
10-
/// If the array is empty, returns empty string
10+
/// If the array is empty, returns null
1111
pub fn nth(value: &Value, args: &HashMap<String, Value>) -> Result<Value> {
1212
let arr = try_get_value!("nth", "value", Vec<Value>, value);
1313

1414
if arr.is_empty() {
15-
return Ok(to_value("").unwrap());
15+
return Ok(Value::Null);
1616
}
1717

1818
let index = match args.get("n") {
1919
Some(val) => try_get_value!("nth", "n", usize, val),
2020
None => return Err(Error::msg("The `nth` filter has to have an `n` argument")),
2121
};
2222

23-
Ok(arr.get(index).unwrap_or(&to_value("").unwrap()).to_owned())
23+
Ok(arr.get(index).map(|x| x.to_owned()).unwrap_or(Value::Null))
2424
}
2525

2626
/// Returns the first value of an array
27-
/// If the array is empty, returns empty string
27+
/// If the array is empty, returns null
2828
pub fn first(value: &Value, _: &HashMap<String, Value>) -> Result<Value> {
2929
let mut arr = try_get_value!("first", "value", Vec<Value>, value);
3030

3131
if arr.is_empty() {
32-
Ok(to_value("").unwrap())
32+
Ok(Value::Null)
3333
} else {
3434
Ok(arr.swap_remove(0))
3535
}
3636
}
3737

3838
/// Returns the last value of an array
39-
/// If the array is empty, returns empty string
39+
/// If the array is empty, returns null
4040
pub fn last(value: &Value, _: &HashMap<String, Value>) -> Result<Value> {
4141
let mut arr = try_get_value!("last", "value", Vec<Value>, value);
4242

43-
Ok(arr.pop().unwrap_or_else(|| to_value("").unwrap()))
43+
Ok(arr.pop().unwrap_or(Value::Null))
4444
}
4545

4646
/// Joins all values in the array by the `sep` argument given
4747
/// If no separator is given, it will use `""` (empty string) as separator
48-
/// If the array is empty, returns empty string
48+
/// If the array is empty, returns null
4949
pub fn join(value: &Value, args: &HashMap<String, Value>) -> Result<Value> {
5050
let arr = try_get_value!("join", "value", Vec<Value>, value);
5151
let sep = match args.get("sep") {
@@ -319,7 +319,7 @@ mod tests {
319319
args.insert("n".to_string(), to_value(1).unwrap());
320320
let result = nth(&to_value(&v).unwrap(), &args);
321321
assert!(result.is_ok());
322-
assert_eq!(result.unwrap(), to_value("").unwrap());
322+
assert_eq!(result.unwrap(), Value::Null);
323323
}
324324

325325
#[test]
@@ -335,7 +335,7 @@ mod tests {
335335

336336
let result = first(&to_value(&v).unwrap(), &HashMap::new());
337337
assert!(result.is_ok());
338-
assert_eq!(result.ok().unwrap(), to_value("").unwrap());
338+
assert_eq!(result.ok().unwrap(), Value::Null);
339339
}
340340

341341
#[test]
@@ -351,7 +351,7 @@ mod tests {
351351

352352
let result = last(&to_value(&v).unwrap(), &HashMap::new());
353353
assert!(result.is_ok());
354-
assert_eq!(result.ok().unwrap(), to_value("").unwrap());
354+
assert_eq!(result.ok().unwrap(), Value::Null);
355355
}
356356

357357
#[test]

0 commit comments

Comments
 (0)