mirror of
https://github.com/nushell/nushell.git
synced 2025-08-18 20:58:41 +02:00
# Description This closes #7498, as well as fixes an issue reported in https://github.com/nushell/nushell/pull/7002#issuecomment-1368340773 BEFORE: ``` 〉[{foo: 'bar'} {}] | get foo Error: nu:🐚:column_not_found (link) × Cannot find column ╭─[entry #5:1:1] 1 │ [{foo: 'bar'} {}] | get foo · ────────┬──────── ─┬─ · │ ╰── value originates here · ╰── cannot find column 'Empty cell' ╰──── 〉[{foo: 'bar'} {}].foo ╭───┬─────╮ │ 0 │ bar │ │ 1 │ │ ╰───┴─────╯ ``` AFTER: ``` 〉[{foo: 'bar'} {}] | get foo Error: nu:🐚:column_not_found (link) × Cannot find column ╭─[entry #1:1:1] 1 │ [{foo: 'bar'} {}] | get foo · ─┬ ─┬─ · │ ╰── cannot find column 'foo' · ╰── value originates here ╰──── 〉[{foo: 'bar'} {}].foo Error: nu:🐚:column_not_found (link) × Cannot find column ╭─[entry #3:1:1] 1 │ [{foo: 'bar'} {}].foo · ─┬ ─┬─ · │ ╰── cannot find column 'foo' · ╰── value originates here ╰──── ``` EDIT: This also changes the semantics of `get`/`select` `-i` somewhat. I've decided to leave it like this because it works more intuitively with `default` and `compact`. BEFORE: ``` 〉[{a:1} {b:2} {a:3}] | select -i foo | to nuon null ``` AFTER: ``` 〉[{a:1} {b:2} {a:3}] | select -i foo | to nuon [[foo]; [null], [null], [null]] ``` # User-Facing Changes See above. EDIT: the issue with holes in cases like ` [{foo: 'bar'} {}].foo.0` versus ` [{foo: 'bar'} {}].0.foo` has been resolved. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
@@ -76,7 +76,7 @@ prints out the list properly."#
|
||||
match input {
|
||||
PipelineData::Value(Value::List { vals, .. }, ..) => {
|
||||
// dbg!("value::list");
|
||||
let data = convert_to_list(vals, config, call.head);
|
||||
let data = convert_to_list(vals, config, call.head)?;
|
||||
if let Some(items) = data {
|
||||
Ok(create_grid_output(
|
||||
items,
|
||||
@@ -93,7 +93,7 @@ prints out the list properly."#
|
||||
}
|
||||
PipelineData::ListStream(stream, ..) => {
|
||||
// dbg!("value::stream");
|
||||
let data = convert_to_list(stream, config, call.head);
|
||||
let data = convert_to_list(stream, config, call.head)?;
|
||||
if let Some(items) = data {
|
||||
Ok(create_grid_output(
|
||||
items,
|
||||
@@ -247,11 +247,12 @@ fn create_grid_output(
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn convert_to_list(
|
||||
iter: impl IntoIterator<Item = Value>,
|
||||
config: &Config,
|
||||
head: Span,
|
||||
) -> Option<Vec<(usize, String, String)>> {
|
||||
) -> Result<Option<Vec<(usize, String, String)>>, ShellError> {
|
||||
let mut iter = iter.into_iter().peekable();
|
||||
|
||||
if let Some(first) = iter.peek() {
|
||||
@@ -267,7 +268,7 @@ fn convert_to_list(
|
||||
let mut row = vec![row_num.to_string()];
|
||||
|
||||
if headers.is_empty() {
|
||||
row.push(item.into_string(", ", config))
|
||||
row.push(item.nonerror_into_string(", ", config)?)
|
||||
} else {
|
||||
for header in headers.iter().skip(1) {
|
||||
let result = match item {
|
||||
@@ -277,12 +278,13 @@ fn convert_to_list(
|
||||
span: head,
|
||||
}],
|
||||
false,
|
||||
false,
|
||||
),
|
||||
_ => Ok(item.clone()),
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(value) => row.push(value.into_string(", ", config)),
|
||||
Ok(value) => row.push(value.nonerror_into_string(", ", config)?),
|
||||
Err(_) => row.push(String::new()),
|
||||
}
|
||||
}
|
||||
@@ -315,9 +317,9 @@ fn convert_to_list(
|
||||
}
|
||||
}
|
||||
|
||||
Some(interleaved)
|
||||
Ok(Some(interleaved))
|
||||
} else {
|
||||
None
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,10 +5,10 @@ use nu_engine::{column::get_columns, env_to_string, CallExt};
|
||||
use nu_protocol::TrimStrategy;
|
||||
use nu_protocol::{
|
||||
ast::{Call, PathMember},
|
||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
||||
format_error, Category, Config, DataSource, Example, FooterMode, IntoPipelineData, ListStream,
|
||||
PipelineData, PipelineMetadata, RawStream, ShellError, Signature, Span, SyntaxShape,
|
||||
TableIndexMode, Type, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Config, DataSource, Example, FooterMode, IntoPipelineData, ListStream, PipelineData,
|
||||
PipelineMetadata, RawStream, ShellError, Signature, Span, SyntaxShape, TableIndexMode, Type,
|
||||
Value,
|
||||
};
|
||||
use nu_table::{string_width, Table as NuTable, TableConfig, TableTheme};
|
||||
use nu_utils::get_ls_colors;
|
||||
@@ -331,12 +331,9 @@ fn handle_table_command(
|
||||
Ok(val.into_pipeline_data())
|
||||
}
|
||||
PipelineData::Value(Value::Error { error }, ..) => {
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
Ok(Value::String {
|
||||
val: format_error(&working_set, &error),
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
// Propagate this error outward, so that it goes to stderr
|
||||
// instead of stdout.
|
||||
Err(error)
|
||||
}
|
||||
PipelineData::Value(Value::CustomValue { val, span }, ..) => {
|
||||
let base_pipeline = val.to_base_value(span)?.into_pipeline_data();
|
||||
@@ -903,7 +900,7 @@ fn convert_to_table(
|
||||
val: text.clone(),
|
||||
span: head,
|
||||
};
|
||||
let val = item.clone().follow_cell_path(&[path], false);
|
||||
let val = item.clone().follow_cell_path(&[path], false, false);
|
||||
|
||||
match val {
|
||||
Ok(val) => DeferredStyleComputation::Value { value: val },
|
||||
@@ -1264,7 +1261,7 @@ fn create_table2_entry_basic(
|
||||
Value::Record { .. } => {
|
||||
let val = header.to_owned();
|
||||
let path = PathMember::String { val, span: head };
|
||||
let val = item.clone().follow_cell_path(&[path], false);
|
||||
let val = item.clone().follow_cell_path(&[path], false, false);
|
||||
|
||||
match val {
|
||||
Ok(val) => value_to_styled_string(&val, config, style_computer),
|
||||
@@ -1292,7 +1289,7 @@ fn create_table2_entry(
|
||||
Value::Record { .. } => {
|
||||
let val = header.to_owned();
|
||||
let path = PathMember::String { val, span: head };
|
||||
let val = item.clone().follow_cell_path(&[path], false);
|
||||
let val = item.clone().follow_cell_path(&[path], false, false);
|
||||
|
||||
match val {
|
||||
Ok(val) => convert_to_table2_entry(
|
||||
|
Reference in New Issue
Block a user