Allow appending table literals. (#2693)

This commit is contained in:
Andrés N. Robalino 2020-10-22 03:26:30 -05:00 committed by GitHub
parent 1d833ef972
commit 77ffd06715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 32 deletions

View File

@ -6,7 +6,7 @@ use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
#[derive(Deserialize)] #[derive(Deserialize)]
struct Arguments { struct Arguments {
row: Value, value: Value,
} }
pub struct Command; pub struct Command;
@ -26,7 +26,7 @@ impl WholeStreamCommand for Command {
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
"Append the given row to the table" "Append a row to the table"
} }
async fn run( async fn run(
@ -34,30 +34,57 @@ impl WholeStreamCommand for Command {
args: CommandArgs, args: CommandArgs,
registry: &CommandRegistry, registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let (Arguments { mut row }, input) = args.process(registry).await?; let (Arguments { mut value }, input) = args.process(registry).await?;
let input: Vec<Value> = input.collect().await; let input: Vec<Value> = input.collect().await;
if let Some(first) = input.get(0) { if let Some(first) = input.get(0) {
row.tag = first.tag(); value.tag = first.tag();
} }
Ok( // Checks if we are trying to append a row literal
futures::stream::iter(input.into_iter().chain(vec![row]).map(ReturnSuccess::value)) if let Value {
.to_output_stream(), value: UntaggedValue::Table(values),
tag,
} = &value
{
if values.len() == 1 && values[0].is_row() {
value = values[0].value.clone().into_value(tag);
}
}
Ok(futures::stream::iter(
input
.into_iter()
.chain(vec![value])
.map(ReturnSuccess::value),
) )
.to_output_stream())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { use nu_protocol::row;
description: "Add something to the end of a list or table",
example: "echo [1 2 3] | append 4", vec![
result: Some(vec![ Example {
UntaggedValue::int(1).into(), description: "Add values to the end of the table",
UntaggedValue::int(2).into(), example: "echo [1 2 3] | append 4",
UntaggedValue::int(3).into(), result: Some(vec![
UntaggedValue::int(4).into(), UntaggedValue::int(1).into(),
]), UntaggedValue::int(2).into(),
}] UntaggedValue::int(3).into(),
UntaggedValue::int(4).into(),
]),
},
Example {
description: "Add row value to the end of the table",
example: "echo [[country]; [Ecuador] ['New Zealand']] | append [[country]; [USA]]",
result: Some(vec![
row! { "country".into() => Value::from("Ecuador")},
row! { "country".into() => Value::from("New Zealand")},
row! { "country".into() => Value::from("USA")},
]),
},
]
} }
} }

View File

@ -1,21 +1,23 @@
# append # append
This command allows you to append the given row to the table. Append a row to the table.
**Note**:
- `append` does not change a file itself. If you want to save your changes, you need to run the `save` command
- if you want to add something containing a whitespace character, you need to put it in quotation marks
## Examples ## Examples
Let's add more cities to this table: Given the following text file `cities.txt` containing cities:
```shell
Canberra
London
Nairobi
Washington
```
And getting back a Nu table:
```shell ```shell
> open cities.txt | lines > open cities.txt | lines
───┬──────────── ───┬────────────
# │
───┼────────────
0 │ Canberra 0 │ Canberra
1 │ London 1 │ London
2 │ Nairobi 2 │ Nairobi
@ -23,13 +25,11 @@ Let's add more cities to this table:
───┴──────────── ───┴────────────
``` ```
You can add a new row by using `append`: Add the city named `Beijing` like so:
```shell ```shell
> open cities.txt | lines | append Beijing > open cities.txt | lines | append Beijing
───┬──────────── ───┬────────────
# │
───┼────────────
0 │ Canberra 0 │ Canberra
1 │ London 1 │ London
2 │ Nairobi 2 │ Nairobi
@ -38,13 +38,11 @@ You can add a new row by using `append`:
───┴──────────── ───┴────────────
``` ```
It's not possible to add multiple rows at once, so you'll need to call `append` multiple times: It's not possible to add multiple rows at once, so you'll need to use `append` multiple times:
```shell ```shell
> open cities.txt | lines | append Beijing | append "Buenos Aires" > open cities.txt | lines | append Beijing | append "Buenos Aires"
───┬────────────── ───┬──────────────
# │
───┼──────────────
0 │ Canberra 0 │ Canberra
1 │ London 1 │ London
2 │ Nairobi 2 │ Nairobi
@ -53,3 +51,55 @@ It's not possible to add multiple rows at once, so you'll need to call `append`
5 │ Buenos Aires 5 │ Buenos Aires
───┴────────────── ───┴──────────────
``` ```
So far we have been working with a table without a column, which leaves us with plain rows. Let's `wrap` the plain rows into a column called `city` and save it as a json file called `cities.json`:
Before we save, let's check how it looks after wrapping:
```shell
open cities.txt | lines | wrap city
───┬────────────
# │ city
───┼────────────
0 │ Canberra
1 │ London
2 │ Nairobi
3 │ Washington
───┴────────────
```
And save:
`> open cities.txt | lines | wrap city | save cities.json`
Since we will be working with rows that have a column, appending like before won't quite give us back what we want:
```shell
> open cities.json | append Guayaquil
───┬────────────
# │ city
───┼────────────
0 │ Canberra
1 │ London
2 │ Nairobi
3 │ Washington
───┴────────────
───┬───────────
4 │ Guayaquil
───┴───────────
```
We append a row literal directly:
```shell
> open cities.json | append [[city]; [Guayaquil]]
───┬────────────
# │ city
───┼────────────
0 │ Canberra
1 │ London
2 │ Nairobi
3 │ Washington
4 │ Guayaquil
───┴────────────
```