mirror of
https://github.com/nushell/nushell
synced 2024-12-26 13:03:07 +00:00
Columnpath support when passing fields for formatting. (#1472)
This commit is contained in:
parent
54bf671a50
commit
db16b56fe1
4 changed files with 76 additions and 23 deletions
|
@ -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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
2
tests/fixtures/formats/cargo_sample.toml
vendored
2
tests/fixtures/formats/cargo_sample.toml
vendored
|
@ -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"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue