default to $nothing if cellpath not found (#6535)

* default to  if cellpath not found

* fmt

* add test

* fix test

* fix clippy

* move behaviour behind `-i` flag

* prevent any possibility of an unspanned error

* ignore all errors

* seperate testes

* fmt
This commit is contained in:
pwygab 2022-09-13 21:17:16 +08:00 committed by GitHub
parent df6a7b6f5c
commit 12a0fe39f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 5 deletions

View File

@ -28,7 +28,7 @@ impl Command for Get {
.rest("rest", SyntaxShape::CellPath, "additional cell paths")
.switch(
"ignore-errors",
"return nothing if path can't be found",
"when there are empty cells, instead of erroring out, replace them with nothing",
Some('i'),
)
.switch(

View File

@ -17,6 +17,11 @@ impl Command for Select {
// FIXME: also add support for --skip
fn signature(&self) -> Signature {
Signature::build("select")
.switch(
"ignore-errors",
"when a column has empty cells, instead of erroring out, replace them with nothing",
Some('i'),
)
.rest(
"rest",
SyntaxShape::CellPath,
@ -42,8 +47,9 @@ impl Command for Select {
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
let span = call.head;
let ignore_empty = call.has_flag("ignore-errors");
select(engine_state, span, columns, input)
select(engine_state, span, columns, input, ignore_empty)
}
fn examples(&self) -> Vec<Example> {
@ -67,6 +73,7 @@ fn select(
span: Span,
columns: Vec<CellPath>,
input: PipelineData,
ignore_empty: bool,
) -> Result<PipelineData, ShellError> {
let mut rows = vec![];
@ -121,6 +128,7 @@ fn select(
..,
) => {
let mut output = vec![];
let mut columns_with_value = Vec::new();
for input_val in input_vals {
if !columns.is_empty() {
@ -128,11 +136,26 @@ fn select(
let mut vals = vec![];
for path in &columns {
//FIXME: improve implementation to not clone
let fetcher = input_val.clone().follow_cell_path(&path.members, false)?;
if ignore_empty {
let fetcher = input_val.clone().follow_cell_path(&path.members, false);
cols.push(path.into_string().replace('.', "_"));
if let Ok(fetcher) = fetcher {
vals.push(fetcher);
if !columns_with_value.contains(&path) {
columns_with_value.push(path);
}
} else {
vals.push(Value::nothing(span));
}
} else {
let fetcher =
input_val.clone().follow_cell_path(&path.members, false)?;
cols.push(path.into_string().replace('.', "_"));
vals.push(fetcher);
}
}
output.push(Value::Record { cols, vals, span })
} else {

View File

@ -159,3 +159,27 @@ fn selects_many_rows() {
assert_eq!(actual.out, "2");
});
}
#[test]
fn select_ignores_errors_succesfully1() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[{a: 1, b: 2} {a: 3, b: 5} {a: 3}] | select -i b
"#
));
assert!(actual.err.is_empty());
}
#[test]
fn select_ignores_errors_succesfully2() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[{a: 1} {a: 2} {a: 3}] | select -i b
"#
));
assert!(actual.err.is_empty());
}