From 071faae772447afd88cf2e3aadefc67fbf652cb8 Mon Sep 17 00:00:00 2001 From: Solomon Date: Wed, 25 Sep 2024 12:48:16 +0000 Subject: [PATCH] fix `inspect` and `explore` panics on empty records (#13893) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Fixes a couple panics: ``` > {} | inspect Error: x Main thread panicked. |-> at crates/nu-command/src/debug/inspect_table.rs:87:15 `-> attempt to divide by zero ``` ``` > {} | explore # see an empty column, press Down Error: x Main thread panicked. |-> at crates/nu-explore/src/views/cursor/mod.rs:39:9 `-> attempt to subtract with overflow ``` # User-Facing Changes `{} | inspect` now outputs an empty table: ``` ╭─────────────┬────────╮ │ description │ record │ ├─────────────┴────────┤ │ │ ├──────────────────────┤ ``` `{} | explore` opens the help menu. Both match the empty list behavior. # Tests I'm not sure how to test `explore`, as it waits for interaction. --- crates/nu-command/src/debug/inspect_table.rs | 15 +++++++++++---- crates/nu-command/tests/commands/inspect.rs | 12 ++++++++++++ crates/nu-explore/src/nu_common/value.rs | 11 +++++++++-- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/crates/nu-command/src/debug/inspect_table.rs b/crates/nu-command/src/debug/inspect_table.rs index e30a8bedcf..f7195992a8 100644 --- a/crates/nu-command/src/debug/inspect_table.rs +++ b/crates/nu-command/src/debug/inspect_table.rs @@ -152,7 +152,7 @@ fn truncate_data( let left_space = expected_width - width; let has_space_for_truncation_column = left_space > PAD; if !has_space_for_truncation_column { - peak_count -= 1; + peak_count = peak_count.saturating_sub(1); } remove_columns(data, peak_count); @@ -201,11 +201,18 @@ mod util { Value::Record { val: record, .. } => { let (cols, vals): (Vec<_>, Vec<_>) = record.into_owned().into_iter().unzip(); ( - cols, - vec![vals + match cols.is_empty() { + true => vec![String::from("")], + false => cols, + }, + match vals .into_iter() .map(|s| debug_string_without_formatting(&s)) - .collect()], + .collect::>() + { + vals if vals.is_empty() => vec![], + vals => vec![vals], + }, ) } Value::List { vals, .. } => { diff --git a/crates/nu-command/tests/commands/inspect.rs b/crates/nu-command/tests/commands/inspect.rs index efa401479b..5917b72e5f 100644 --- a/crates/nu-command/tests/commands/inspect.rs +++ b/crates/nu-command/tests/commands/inspect.rs @@ -5,3 +5,15 @@ fn inspect_with_empty_pipeline() { let actual = nu!("inspect"); assert!(actual.err.contains("no input value was piped in")); } + +#[test] +fn inspect_with_empty_list() { + let actual = nu!("[] | inspect"); + assert!(actual.out.contains("empty list")); +} + +#[test] +fn inspect_with_empty_record() { + let actual = nu!("{} | inspect"); + assert!(actual.out.contains("empty record")); +} diff --git a/crates/nu-explore/src/nu_common/value.rs b/crates/nu-explore/src/nu_common/value.rs index ae90278358..3b5751c11a 100644 --- a/crates/nu-explore/src/nu_common/value.rs +++ b/crates/nu-explore/src/nu_common/value.rs @@ -92,8 +92,15 @@ pub fn collect_input(value: Value) -> Result<(Vec, Vec>)> { let span = value.span(); match value { Value::Record { val: record, .. } => { - let (key, val) = record.into_owned().into_iter().unzip(); - Ok((key, vec![val])) + let (key, val): (_, Vec) = record.into_owned().into_iter().unzip(); + + Ok(( + key, + match val.is_empty() { + true => vec![], + false => vec![val], + }, + )) } Value::List { vals, .. } => { let mut columns = get_columns(&vals);