Update description and error types for split-by (#10865)

# Description

`split-by` only works on a `Record`, the error type was updated to
match, and now uses a more-specific type. (Two type fixes for the price
of one!)

The `usage` was updated to say "record" as well

# User-Facing Changes

* Providing the wrong type to `split-by` now gives an error messages
with the correct required input type

Previously:

```
❯ ls | get name | split-by type
Error:   × unsupported input
   ╭─[entry #267:1:1]
 1 │ ls | get name | split-by type
   ·      ─┬─
   ·       ╰── requires a table with one row for splitting
   ╰────
```

With this PR:

```
❯ ls | get name | split-by type
Error: nu:🐚:type_mismatch

  × Type mismatch.
   ╭─[entry #1:1:1]
 1 │ ls | get name | split-by type
   ·      ─┬─
   ·       ╰── requires a record to split
   ╰────
```

# Tests + Formatting

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting

Only generated commands need to be updated

---------

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
This commit is contained in:
Eric Hodel
2023-11-07 07:27:10 -08:00
committed by GitHub
parent 9b202d560d
commit c039e4b3d0
2 changed files with 41 additions and 28 deletions

View File

@ -23,7 +23,7 @@ impl Command for SplitBy {
}
fn usage(&self) -> &str {
"Create a new table split."
"Split a record into groups"
}
fn run(
@ -40,13 +40,13 @@ impl Command for SplitBy {
vec![Example {
description: "split items by column named \"lang\"",
example: r#"{
'2019': [
{ name: 'andres', lang: 'rb', year: '2019' },
{ name: 'jt', lang: 'rs', year: '2019' }
],
'2021': [
{ name: 'storm', lang: 'rs', 'year': '2021' }
]
'2019': [
{ name: 'andres', lang: 'rb', year: '2019' },
{ name: 'jt', lang: 'rs', year: '2019' }
],
'2021': [
{ name: 'storm', lang: 'rs', 'year': '2021' }
]
} | split-by lang"#,
result: Some(Value::test_record(record! {
"rb" => Value::test_record(record! {
@ -176,7 +176,7 @@ fn data_group(
pub fn data_split(
value: PipelineData,
splitter: Option<&dyn Fn(usize, &Value) -> Result<String, ShellError>>,
span: Span,
dst_span: Span,
) -> Result<PipelineData, ShellError> {
let mut splits = indexmap::IndexMap::new();
@ -202,33 +202,31 @@ pub fn data_split(
}
}
_ => {
return Err(ShellError::GenericError(
"unsupported input".into(),
"requires a table with one row for splitting".into(),
Some(span),
None,
Vec::new(),
))
return Err(ShellError::OnlySupportsThisInputType {
exp_input_type: "Record".into(),
wrong_type: v.get_type().to_string(),
dst_span,
src_span: v.span(),
})
}
}
}
PipelineData::Empty => return Err(ShellError::PipelineEmpty { dst_span }),
_ => {
return Err(ShellError::GenericError(
"unsupported input".into(),
"requires a table with one row for splitting".into(),
Some(span),
None,
Vec::new(),
))
return Err(ShellError::PipelineMismatch {
exp_input_type: "record".into(),
dst_span,
src_span: value.span().unwrap_or(Span::unknown()),
})
}
}
let record = splits
.into_iter()
.map(|(k, rows)| (k, Value::record(rows.into_iter().collect(), span)))
.map(|(k, rows)| (k, Value::record(rows.into_iter().collect(), dst_span)))
.collect();
Ok(PipelineData::Value(Value::record(record, span), None))
Ok(PipelineData::Value(Value::record(record, dst_span), None))
}
#[cfg(test)]