get :: support fetching rows using numbers in column path.

This commit is contained in:
Andrés N. Robalino 2019-10-31 14:20:22 -05:00
parent 7f18ff10b2
commit e31ed66610
2 changed files with 121 additions and 7 deletions

View file

@ -533,10 +533,21 @@ impl Value {
) -> Result<Option<Tagged<&Value>>, ShellError> { ) -> Result<Option<Tagged<&Value>>, ShellError> {
let mut current = self; let mut current = self;
for p in path { for p in path {
// note:
// This will eventually be refactored once we are able
// to parse correctly column_paths and get them deserialized
// to values for us.
let value = match p.item().parse::<usize>() { let value = match p.item().parse::<usize>() {
Ok(number) => current.get_data_by_index(number), Ok(number) => match current {
Err(_) => current.get_data_by_key(p), Value::Table(_) => current.get_data_by_index(number),
}; Value::Row(_) => current.get_data_by_key(p),
_ => None,
},
Err(_) => match self {
Value::Table(_) | Value::Row(_) => current.get_data_by_key(p),
_ => None,
},
}; // end
match value { match value {
Some(v) => current = v, Some(v) => current = v,
@ -1022,7 +1033,7 @@ mod tests {
} }
#[test] #[test]
fn column_path_that_contains_just_a_numbers_gets_a_row_from_a_table() { fn column_path_that_contains_just_a_number_gets_a_row_from_a_table() {
let field_path = column_path(&vec![string("package"), string("authors"), string("0")]); let field_path = column_path(&vec![string("package"), string("authors"), string("0")]);
let (_, tag) = string("Andrés N. Robalino").into_parts(); let (_, tag) = string("Andrés N. Robalino").into_parts();
@ -1050,6 +1061,35 @@ mod tests {
); );
} }
#[test]
fn column_path_that_contains_just_a_number_gets_a_row_from_a_row() {
let field_path = column_path(&vec![string("package"), string("authors"), string("0")]);
let (_, tag) = string("Andrés N. Robalino").into_parts();
let value = Value::row(indexmap! {
"package".into() => row(indexmap! {
"name".into() => string("nu"),
"version".into() => string("0.4.0"),
"authors".into() => row(indexmap! {
"0".into() => row(indexmap!{"name".into() => string("Andrés N. Robalino")}),
"1".into() => row(indexmap!{"name".into() => string("Jonathan Turner")}),
"2".into() => row(indexmap!{"name".into() => string("Yehuda Katz")}),
})
})
});
assert_eq!(
**value
.get_data_by_column_path(tag, &field_path, Box::new(error_callback()))
.unwrap()
.unwrap(),
Value::row(indexmap! {
"name".into() => string("Andrés N. Robalino")
})
);
}
#[test] #[test]
fn replaces_matching_field_from_a_row() { fn replaces_matching_field_from_a_row() {
let field_path = column_path(&vec![string("amigos")]); let field_path = column_path(&vec![string("amigos")]);

View file

@ -52,10 +52,61 @@ fn fetches_by_index_from_a_given_table() {
assert_eq!(actual, "Andrés N. Robalino <andres@androbtech.com>"); assert_eq!(actual, "Andrés N. Robalino <andres@androbtech.com>");
}) })
} }
#[test]
fn supports_fetching_rows_from_tables_using_columns_named_as_numbers() {
Playground::setup("get_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
0 = "nu"
1 = "0.4.1"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open sample.toml
| get package.1
| echo $it
"#
));
assert_eq!(actual, "0.4.1");
})
}
#[test]
fn can_fetch_tables_or_rows_using_numbers_in_column_path() {
Playground::setup("get_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
0 = "nu"
1 = "0.4.1"
2 = ["Yehuda Katz <wycats@gmail.com>", "Jonathan Turner <jonathan.d.turner@gmail.com>", "Andrés N. Robalino <andres@androbtech.com>"]
description = "When arepas shells are tasty and fun."
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open sample.toml
| get package.2.1
| echo $it
"#
));
assert_eq!(actual, "Jonathan Turner <jonathan.d.turner@gmail.com>");
})
}
#[test] #[test]
fn fetches_more_than_one_column_member_path() { fn fetches_more_than_one_column_member_path() {
Playground::setup("get_test_3", |dirs, sandbox| { Playground::setup("get_test_5", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent( sandbox.with_files(vec![FileWithContent(
"sample.toml", "sample.toml",
r#" r#"
@ -87,9 +138,32 @@ fn fetches_more_than_one_column_member_path() {
}) })
} }
#[test]
fn errors_fetching_by_column_not_present() {
Playground::setup("get_test_6", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[taconushell]
sentence_words = ["Yo", "quiero", "taconushell"]
"#,
)]);
let actual = nu_error!(
cwd: dirs.test(), h::pipeline(
r#"
open sample.toml
| get taco
"#
));
assert!(actual.contains("Unknown column"));
assert!(actual.contains("did you mean 'taconushell'?"));
})
}
#[test] #[test]
fn errors_fetching_by_index_out_of_bounds_from_table() { fn errors_fetching_by_index_out_of_bounds_from_table() {
Playground::setup("get_test_4", |dirs, sandbox| { Playground::setup("get_test_7", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent( sandbox.with_files(vec![FileWithContent(
"sample.toml", "sample.toml",
r#" r#"
@ -114,7 +188,7 @@ fn errors_fetching_by_index_out_of_bounds_from_table() {
#[test] #[test]
fn requires_at_least_one_column_member_path() { fn requires_at_least_one_column_member_path() {
Playground::setup("get_test_5", |dirs, sandbox| { Playground::setup("get_test_8", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("andres.txt")]); sandbox.with_files(vec![EmptyFile("andres.txt")]);
let actual = nu_error!( let actual = nu_error!(