Columnpath support when passing fields for formatting. (#1472)

This commit is contained in:
Andrés N. Robalino 2020-03-10 01:55:03 -05:00 committed by GitHub
parent 54bf671a50
commit db16b56fe1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 23 deletions

View file

@ -2,7 +2,11 @@ use crate::commands::PerItemCommand;
use crate::context::CommandRegistry; use crate::context::CommandRegistry;
use crate::prelude::*; use crate::prelude::*;
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_protocol::{CallInfo, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; use nu_protocol::{
CallInfo, ColumnPath, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
};
use nu_source::Tagged;
use nu_value_ext::{as_column_path, get_data_by_column_path};
use std::borrow::Borrow; use std::borrow::Borrow;
use nom::{ use nom::{
@ -45,35 +49,46 @@ impl PerItemCommand for Format {
ShellError::labeled_error( ShellError::labeled_error(
"Could not create format pattern", "Could not create format pattern",
"could not create format pattern", "could not create format pattern",
pattern_tag, &pattern_tag,
) )
})?; })?;
let commands = format_pattern.1; let commands = format_pattern.1;
let output = if let Value { let output = match value {
value: UntaggedValue::Row(dict), value
.. @
} = value Value {
{ value: UntaggedValue::Row(_),
let mut output = String::new(); ..
} => {
let mut output = String::new();
for command in &commands { for command in &commands {
match command { match command {
FormatCommand::Text(s) => { FormatCommand::Text(s) => {
output.push_str(s); output.push_str(s);
} }
FormatCommand::Column(c) => { FormatCommand::Column(c) => {
if let Some(c) = dict.entries.get(c) { let key = to_column_path(&c, &pattern_tag)?;
output.push_str(&value::format_leaf(c.borrow()).plain_string(100_000))
let fetcher = get_data_by_column_path(
&value,
&key,
Box::new(move |(_, _, error)| error),
);
if let Ok(c) = fetcher {
output
.push_str(&value::format_leaf(c.borrow()).plain_string(100_000))
}
// That column doesn't match, so don't emit anything
} }
// That column doesn't match, so don't emit anything
} }
} }
}
output output
} else { }
String::new() _ => String::new(),
}; };
Ok(futures::stream::iter(vec![ReturnSuccess::value( Ok(futures::stream::iter(vec![ReturnSuccess::value(
@ -116,3 +131,27 @@ fn format(input: &str) -> IResult<&str, Vec<FormatCommand>> {
Ok((loop_input, output)) Ok((loop_input, output))
} }
fn to_column_path(
path_members: &str,
tag: impl Into<Tag>,
) -> Result<Tagged<ColumnPath>, ShellError> {
let tag = tag.into();
as_column_path(
&UntaggedValue::Table(
path_members
.split('.')
.map(|x| {
let member = match x.parse::<u64>() {
Ok(v) => UntaggedValue::int(v),
Err(_) => UntaggedValue::string(x),
};
member.into_value(&tag)
})
.collect(),
)
.into_value(&tag),
)
}

View file

@ -14,3 +14,17 @@ fn creates_the_resulting_string_from_the_given_fields() {
assert_eq!(actual, "nu has license ISC"); assert_eq!(actual, "nu has license ISC");
} }
#[test]
fn given_fields_can_be_column_paths() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| format "{package.name} is {package.description}"
| echo $it
"#
));
assert_eq!(actual, "nu is a new type of shell");
}

View file

@ -42,6 +42,6 @@ fn writes_out_csv() {
); );
let actual = file_contents(expected_file); let actual = file_contents(expected_file);
assert!(actual.contains("[Table],A shell for the GitHub era,2018,ISC,nu,0.1.1")); assert!(actual.contains("[Table],a new type of shell,2018,ISC,nu,0.1.1"));
}) })
} }

View file

@ -2,7 +2,7 @@
name = "nu" name = "nu"
version = "0.1.1" version = "0.1.1"
authors = ["Yehuda Katz <wycats@gmail.com>"] authors = ["Yehuda Katz <wycats@gmail.com>"]
description = "A shell for the GitHub era" description = "a new type of shell"
license = "ISC" license = "ISC"
edition = "2018" edition = "2018"