Remove default list-diving behaviour (#13386)

# Description

Before this change `default` would dive into lists and replace `null`
elements with the default value.
Therefore there was no easy way to process `null|list<null|string>`
input and receive `list<null|string>`
(IOW to apply the default on the top level only).

However it's trivially easy to apply default values to list elements
with the `each` command:
```nushell
[null, "a", null] | each { default "b" }
```

So there's no need to have this behavior in `default` command.

# User-Facing Changes

* `default` no longer dives into lists to replace `null` elements with
the default value.

# Tests + Formatting

Added a couple of tests for the new (and old) behavior.

# After Submitting

* Update docs.
This commit is contained in:
Bruce Weirdan 2024-07-16 05:54:24 +02:00 committed by GitHub
parent 0918050ac8
commit fcb8e36caa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 11 deletions

View File

@ -51,11 +51,11 @@ impl Command for Default {
description:
"Get the env value of `MY_ENV` with a default value 'abc' if not present",
example: "$env | get --ignore-errors MY_ENV | default 'abc'",
result: None, // Some(Value::test_string("abc")),
result: Some(Value::test_string("abc")),
},
Example {
description: "Replace the `null` value in a list",
example: "[1, 2, null, 4] | default 3",
example: "[1, 2, null, 4] | each { default 3 }",
result: Some(Value::list(
vec![
Value::test_int(1),
@ -113,15 +113,7 @@ fn default(
} else if input.is_nothing() {
Ok(value.into_pipeline_data())
} else {
input
.map(
move |item| match item {
Value::Nothing { .. } => value.clone(),
x => x,
},
engine_state.signals(),
)
.map(|x| x.set_metadata(metadata))
Ok(input)
}
}

View File

@ -32,3 +32,15 @@ fn default_after_empty_filter() {
assert_eq!(actual.out, "d");
}
#[test]
fn keeps_nulls_in_lists() {
let actual = nu!(r#"[null, 2, 3] | default [] | to json -r"#);
assert_eq!(actual.out, "[null,2,3]");
}
#[test]
fn replaces_null() {
let actual = nu!(r#"null | default 1"#);
assert_eq!(actual.out, "1");
}