Error on negative argument to last (#7184)

# Description

- Error on negative argument to `last`
- Add test for negative value in last

Follow-up for #7178

# User-Facing Changes

Breaking change:

even before #7178 `last` returned an empty `list<any>` when given
negative indices.
Now this is an
[error](https://docs.rs/nu-protocol/latest/nu_protocol/enum.ShellError.html#variant.NeedsPositiveValue)

Note:
In #7136 we are considering supporting negative indexing

# Tests + Formatting

+ 1 failure test

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
Stefan Holderbach 2022-11-23 05:04:04 +01:00 committed by GitHub
parent 21dedef7f6
commit ce03d8eb12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 8 deletions

View File

@ -77,14 +77,18 @@ impl Command for Last {
let span = call.head; let span = call.head;
let rows: Option<i64> = call.opt(engine_state, stack, 0)?; let rows: Option<i64> = call.opt(engine_state, stack, 0)?;
let to_keep = rows.unwrap_or(1).try_into().unwrap_or(0); let to_keep = match rows.unwrap_or(1) {
0 => {
// early exit for `last 0` // early exit for `last 0`
if to_keep == 0 {
return Ok(Vec::<Value>::new() return Ok(Vec::<Value>::new()
.into_pipeline_data(engine_state.ctrlc.clone()) .into_pipeline_data(engine_state.ctrlc.clone())
.set_metadata(metadata)); .set_metadata(metadata));
} }
i if i < 0 => {
return Err(ShellError::NeedsPositiveValue(span));
}
i => i as usize,
};
// only keep last `to_keep` rows in memory // only keep last `to_keep` rows in memory
let mut buf = VecDeque::<_>::new(); let mut buf = VecDeque::<_>::new();

View File

@ -78,3 +78,16 @@ fn gets_last_row_as_list_when_amount_given() {
assert_eq!(actual.out, "list<int>"); assert_eq!(actual.out, "list<int>");
} }
#[test]
fn last_errors_on_negative_index() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[1, 2, 3]
| last -2
"#
));
assert!(actual.err.contains("use a positive value"));
}