From 62575c9a4f7346cbc28f6461dac2aaa12d06aca7 Mon Sep 17 00:00:00 2001 From: Stefan Holderbach Date: Mon, 6 Mar 2023 18:33:09 +0100 Subject: [PATCH] Document and critically review `ShellError` variants - Ep. 3 (#8340) Continuation of #8229 and #8326 # Description The `ShellError` enum at the moment is kind of messy. Many variants are basic tuple structs where you always have to reference the implementation with its macro invocation to know which field serves which purpose. Furthermore we have both variants that are kind of redundant or either overly broad to be useful for the user to match on or overly specific with few uses. So I set out to start fixing the lacking documentation and naming to make it feasible to critically review the individual usages and fix those. Furthermore we can decide to join or split up variants that don't seem to be fit for purpose. # Call to action **Everyone:** Feel free to add review comments if you spot inconsistent use of `ShellError` variants. # User-Facing Changes (None now, end goal more explicit and consistent error messages) # Tests + Formatting (No additional tests needed so far) # Commits (so far) - Remove `ShellError::FeatureNotEnabled` - Name fields on `SE::ExternalNotSupported` - Name field on `SE::InvalidProbability` - Name fields on `SE::NushellFailed` variants - Remove unused `SE::NushellFailedSpannedHelp` - Name field on `SE::VariableNotFoundAtRuntime` - Name fields on `SE::EnvVarNotFoundAtRuntime` - Name fields on `SE::ModuleNotFoundAtRuntime` - Remove usused `ModuleOrOverlayNotFoundAtRuntime` - Name fields on `SE::OverlayNotFoundAtRuntime` - Name field on `SE::NotFound` --- .../nu-cmd-lang/src/core_commands/const_.rs | 10 +- crates/nu-cmd-lang/src/core_commands/do_.rs | 17 +- crates/nu-cmd-lang/src/core_commands/help.rs | 20 +- .../src/core_commands/help_modules.rs | 8 +- .../nu-cmd-lang/src/core_commands/hide_env.rs | 5 +- crates/nu-cmd-lang/src/core_commands/if_.rs | 12 +- .../src/core_commands/overlay/hide.rs | 15 +- .../src/core_commands/overlay/use_.rs | 28 +- .../nu-cmd-lang/src/core_commands/while_.rs | 12 +- crates/nu-command/src/charting/histogram.rs | 10 +- .../nu-command/src/conversions/into/bool.rs | 10 +- .../src/conversions/into/datetime.rs | 7 +- .../src/conversions/into/decimal.rs | 12 +- .../src/conversions/into/duration.rs | 58 +- .../src/conversions/into/filesize.rs | 10 +- crates/nu-command/src/conversions/into/int.rs | 69 +-- .../nu-command/src/conversions/into/string.rs | 30 +- .../nu-command/src/database/values/sqlite.rs | 24 +- .../src/dataframe/eager/with_column.rs | 12 +- .../values/nu_dataframe/between_values.rs | 4 +- .../src/dataframe/values/nu_dataframe/mod.rs | 36 +- .../src/dataframe/values/nu_expression/mod.rs | 34 +- .../src/dataframe/values/nu_lazyframe/mod.rs | 34 +- .../dataframe/values/nu_lazygroupby/mod.rs | 22 +- .../src/dataframe/values/nu_when/mod.rs | 22 +- crates/nu-command/src/env/let_env.rs | 8 +- crates/nu-command/src/env/load_env.rs | 15 +- crates/nu-command/src/env/with_env.rs | 26 +- crates/nu-command/src/filesystem/save.rs | 10 +- crates/nu-command/src/filters/first.rs | 4 +- crates/nu-command/src/filters/group_by.rs | 16 +- crates/nu-command/src/filters/move_.rs | 16 +- crates/nu-command/src/filters/split_by.rs | 10 +- crates/nu-command/src/filters/uniq_by.rs | 6 +- crates/nu-command/src/filters/update.rs | 7 +- crates/nu-command/src/filters/upsert.rs | 5 +- crates/nu-command/src/formats/from/json.rs | 20 +- crates/nu-command/src/formats/from/toml.rs | 10 +- crates/nu-command/src/formats/to/delimited.rs | 19 +- crates/nu-command/src/formats/to/json.rs | 10 +- crates/nu-command/src/formats/to/toml.rs | 7 +- crates/nu-command/src/formats/to/xml.rs | 12 +- crates/nu-command/src/formats/to/yaml.rs | 7 +- crates/nu-command/src/network/http/client.rs | 24 +- .../nu-command/src/network/url/build_query.rs | 12 +- crates/nu-command/src/path/relative_to.rs | 7 +- crates/nu-command/src/random/bool.rs | 2 +- crates/nu-command/src/shells/g.rs | 4 +- crates/nu-command/src/shells/mod.rs | 2 +- crates/nu-command/src/sort_utils.rs | 6 +- crates/nu-command/src/system/complete.rs | 10 +- crates/nu-command/src/system/nu_check.rs | 6 +- crates/nu-command/src/system/run_external.rs | 60 +-- crates/nu-engine/src/call_ext.rs | 20 +- crates/nu-engine/src/env.rs | 48 +- crates/nu-engine/src/eval.rs | 28 +- crates/nu-parser/src/known_external.rs | 12 +- .../nu-plugin/src/protocol/evaluated_call.rs | 10 +- crates/nu-plugin/src/protocol/mod.rs | 7 +- crates/nu-protocol/src/alias.rs | 10 +- crates/nu-protocol/src/engine/stack.rs | 8 +- crates/nu-protocol/src/pipeline_data.rs | 10 +- crates/nu-protocol/src/shell_error.rs | 269 ++++++---- crates/nu-protocol/src/value/custom_value.rs | 12 +- crates/nu-protocol/src/value/from.rs | 24 +- crates/nu-protocol/src/value/from_value.rs | 346 ++++++------ crates/nu-protocol/src/value/mod.rs | 500 ++++++++++-------- crates/nu-protocol/src/value/range.rs | 8 +- .../src/cool_custom_value.rs | 24 +- crates/nu_plugin_custom_values/src/main.rs | 12 +- .../src/second_custom_value.rs | 24 +- crates/nu_plugin_formats/src/from/eml.rs | 7 +- 72 files changed, 1193 insertions(+), 1048 deletions(-) diff --git a/crates/nu-cmd-lang/src/core_commands/const_.rs b/crates/nu-cmd-lang/src/core_commands/const_.rs index 0da4efcac6..a051aa567f 100644 --- a/crates/nu-cmd-lang/src/core_commands/const_.rs +++ b/crates/nu-cmd-lang/src/core_commands/const_.rs @@ -60,11 +60,11 @@ impl Command for Const { Ok(PipelineData::empty()) } else { - Err(ShellError::NushellFailedSpanned( - "Missing Constant".to_string(), - "constant not added by the parser".to_string(), - call.head, - )) + Err(ShellError::NushellFailedSpanned { + msg: "Missing Constant".to_string(), + label: "constant not added by the parser".to_string(), + span: call.head, + }) } } diff --git a/crates/nu-cmd-lang/src/core_commands/do_.rs b/crates/nu-cmd-lang/src/core_commands/do_.rs index 4d55e4c2c2..330d906de1 100644 --- a/crates/nu-cmd-lang/src/core_commands/do_.rs +++ b/crates/nu-cmd-lang/src/core_commands/do_.rs @@ -161,11 +161,12 @@ impl Command for Do { let stdout = if let Some(handle) = stdout_handler { match handle.join() { Err(err) => { - return Err(ShellError::ExternalCommand( - "Fail to receive external commands stdout message".to_string(), - format!("{err:?}"), + return Err(ShellError::ExternalCommand { + label: "Fail to receive external commands stdout message" + .to_string(), + help: format!("{err:?}"), span, - )); + }); } Ok(res) => Some(res), } @@ -183,11 +184,11 @@ impl Command for Do { }; if let Some(Value::Int { val: code, .. }) = exit_code.last() { if *code != 0 { - return Err(ShellError::ExternalCommand( - "External command failed".to_string(), - stderr_msg, + return Err(ShellError::ExternalCommand { + label: "External command failed".to_string(), + help: stderr_msg, span, - )); + }); } } diff --git a/crates/nu-cmd-lang/src/core_commands/help.rs b/crates/nu-cmd-lang/src/core_commands/help.rs index 983dbb4c99..92c14c3438 100644 --- a/crates/nu-cmd-lang/src/core_commands/help.rs +++ b/crates/nu-cmd-lang/src/core_commands/help.rs @@ -100,9 +100,15 @@ You can also learn more at https://www.nushell.sh/book/"#; result }; - if let Err(ShellError::ModuleNotFoundAtRuntime(_, _)) = result { + if let Err(ShellError::ModuleNotFoundAtRuntime { + mod_name: _, + span: _, + }) = result + { let rest_spans: Vec = rest.iter().map(|arg| arg.span).collect(); - Err(ShellError::NotFound(span(&rest_spans))) + Err(ShellError::NotFound { + span: span(&rest_spans), + }) } else { result } @@ -144,11 +150,11 @@ pub fn highlight_search_in_table( let (cols, mut vals, record_span) = if let Value::Record { cols, vals, span } = record { (cols, vals, span) } else { - return Err(ShellError::NushellFailedSpanned( - "Expected record".to_string(), - format!("got {}", record.get_type()), - record.span()?, - )); + return Err(ShellError::NushellFailedSpanned { + msg: "Expected record".to_string(), + label: format!("got {}", record.get_type()), + span: record.span()?, + }); }; let has_match = cols.iter().zip(vals.iter_mut()).fold( diff --git a/crates/nu-cmd-lang/src/core_commands/help_modules.rs b/crates/nu-cmd-lang/src/core_commands/help_modules.rs index ed4de90dc4..e42c4abbed 100644 --- a/crates/nu-cmd-lang/src/core_commands/help_modules.rs +++ b/crates/nu-cmd-lang/src/core_commands/help_modules.rs @@ -120,10 +120,10 @@ pub fn help_modules( let module_id = if let Some(id) = engine_state.find_module(name.as_bytes(), &[]) { id } else { - return Err(ShellError::ModuleNotFoundAtRuntime( - name, - span(&rest.iter().map(|r| r.span).collect::>()), - )); + return Err(ShellError::ModuleNotFoundAtRuntime { + mod_name: name, + span: span(&rest.iter().map(|r| r.span).collect::>()), + }); }; let module = engine_state.get_module(module_id); diff --git a/crates/nu-cmd-lang/src/core_commands/hide_env.rs b/crates/nu-cmd-lang/src/core_commands/hide_env.rs index 454e2b2865..b582b32df8 100644 --- a/crates/nu-cmd-lang/src/core_commands/hide_env.rs +++ b/crates/nu-cmd-lang/src/core_commands/hide_env.rs @@ -58,7 +58,10 @@ impl Command for HideEnv { name.span, )); } else { - return Err(ShellError::EnvVarNotFoundAtRuntime(name.item, name.span)); + return Err(ShellError::EnvVarNotFoundAtRuntime { + envvar_name: name.item, + span: name.span, + }); } } } diff --git a/crates/nu-cmd-lang/src/core_commands/if_.rs b/crates/nu-cmd-lang/src/core_commands/if_.rs index cf89e54222..2d8f9c1663 100644 --- a/crates/nu-cmd-lang/src/core_commands/if_.rs +++ b/crates/nu-cmd-lang/src/core_commands/if_.rs @@ -111,12 +111,12 @@ impl Command for If { Ok(PipelineData::empty()) } } - x => Err(ShellError::CantConvert( - "bool".into(), - x.get_type().to_string(), - result.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: x.get_type().to_string(), + span: result.span()?, + help: None, + }), } } diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/hide.rs b/crates/nu-cmd-lang/src/core_commands/overlay/hide.rs index c1127ea42a..f05e069a33 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/hide.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/hide.rs @@ -61,10 +61,10 @@ impl Command for OverlayHide { }; if !stack.is_overlay_active(&overlay_name.item) { - return Err(ShellError::OverlayNotFoundAtRuntime( - overlay_name.item, - overlay_name.span, - )); + return Err(ShellError::OverlayNotFoundAtRuntime { + overlay_name: overlay_name.item, + span: overlay_name.span, + }); } let keep_env: Option>> = @@ -76,7 +76,12 @@ impl Command for OverlayHide { for name in env_var_names_to_keep.into_iter() { match stack.get_env_var(engine_state, &name.item) { Some(val) => env_vars_to_keep.push((name.item, val.clone())), - None => return Err(ShellError::EnvVarNotFoundAtRuntime(name.item, name.span)), + None => { + return Err(ShellError::EnvVarNotFoundAtRuntime { + envvar_name: name.item, + span: name.span, + }) + } } } diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs index 024623426c..4d546abec8 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs @@ -70,18 +70,18 @@ impl Command for OverlayUse { if let Expr::Overlay(module_id) = overlay_expr.expr { module_id } else { - return Err(ShellError::NushellFailedSpanned( - "Not an overlay".to_string(), - "requires an overlay (path or a string)".to_string(), - overlay_expr.span, - )); + return Err(ShellError::NushellFailedSpanned { + msg: "Not an overlay".to_string(), + label: "requires an overlay (path or a string)".to_string(), + span: overlay_expr.span, + }); } } else { - return Err(ShellError::NushellFailedSpanned( - "Missing positional".to_string(), - "missing required overlay".to_string(), - call.head, - )); + return Err(ShellError::NushellFailedSpanned { + msg: "Missing positional".to_string(), + label: "missing required overlay".to_string(), + span: call.head, + }); }; let overlay_name = if let Some(name) = call.opt(engine_state, caller_stack, 1)? { @@ -98,10 +98,10 @@ impl Command for OverlayUse { return Err(ShellError::NonUtf8(name_arg.span)); } } else { - return Err(ShellError::OverlayNotFoundAtRuntime( - name_arg.item, - name_arg.span, - )); + return Err(ShellError::OverlayNotFoundAtRuntime { + overlay_name: name_arg.item, + span: name_arg.span, + }); }; if let Some(module_id) = maybe_origin_module_id { diff --git a/crates/nu-cmd-lang/src/core_commands/while_.rs b/crates/nu-cmd-lang/src/core_commands/while_.rs index afecf36e0c..c3f725a1f5 100644 --- a/crates/nu-cmd-lang/src/core_commands/while_.rs +++ b/crates/nu-cmd-lang/src/core_commands/while_.rs @@ -89,12 +89,12 @@ impl Command for While { } } x => { - return Err(ShellError::CantConvert( - "bool".into(), - x.get_type().to_string(), - result.span()?, - None, - )) + return Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: x.get_type().to_string(), + span: result.span()?, + help: None, + }) } } } diff --git a/crates/nu-command/src/charting/histogram.rs b/crates/nu-command/src/charting/histogram.rs index c667fc9b16..e082b59e4a 100644 --- a/crates/nu-command/src/charting/histogram.rs +++ b/crates/nu-command/src/charting/histogram.rs @@ -204,11 +204,11 @@ fn run_histogram( } if inputs.is_empty() { - return Err(ShellError::CantFindColumn( - col_name.clone(), - head_span, - list_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.clone(), + span: head_span, + src_span: list_span, + }); } } } diff --git a/crates/nu-command/src/conversions/into/bool.rs b/crates/nu-command/src/conversions/into/bool.rs index ed02afdc65..21cc07c591 100644 --- a/crates/nu-command/src/conversions/into/bool.rs +++ b/crates/nu-command/src/conversions/into/bool.rs @@ -134,15 +134,15 @@ fn string_to_boolean(s: &str, span: Span) -> Result { let val = o.parse::(); match val { Ok(f) => Ok(f.abs() >= f64::EPSILON), - Err(_) => Err(ShellError::CantConvert( - "boolean".to_string(), - "string".to_string(), + Err(_) => Err(ShellError::CantConvert { + to_type: "boolean".to_string(), + from_type: "string".to_string(), span, - Some( + help: Some( r#"the strings "true" and "false" can be converted into a bool"# .to_string(), ), - )), + }), } } } diff --git a/crates/nu-command/src/conversions/into/datetime.rs b/crates/nu-command/src/conversions/into/datetime.rs index ba71e5db7d..89653a23a6 100644 --- a/crates/nu-command/src/conversions/into/datetime.rs +++ b/crates/nu-command/src/conversions/into/datetime.rs @@ -307,12 +307,7 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { Ok(d) => Value::Date { val: d, span: head }, Err(reason) => { Value::Error { - error: ShellError::CantConvert( - format!("could not parse as datetime using format '{}'", dt.0), - reason.to_string(), - head, - Some("you can use `into datetime` without a format string to enable flexible parsing".to_string()) - ), + error: ShellError::CantConvert { to_type: format!("could not parse as datetime using format '{}'", dt.0), from_type: reason.to_string(), span: head, help: Some("you can use `into datetime` without a format string to enable flexible parsing".to_string()) }, } } }, diff --git a/crates/nu-command/src/conversions/into/decimal.rs b/crates/nu-command/src/conversions/into/decimal.rs index 5a38fefdbc..30f84fab01 100644 --- a/crates/nu-command/src/conversions/into/decimal.rs +++ b/crates/nu-command/src/conversions/into/decimal.rs @@ -88,12 +88,12 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, head: Span) -> Value { match other.parse::() { Ok(x) => Value::float(x, head), Err(reason) => Value::Error { - error: ShellError::CantConvert( - "float".to_string(), - reason.to_string(), - *span, - None, - ), + error: ShellError::CantConvert { + to_type: "float".to_string(), + from_type: reason.to_string(), + span: *span, + help: None, + }, }, } } diff --git a/crates/nu-command/src/conversions/into/duration.rs b/crates/nu-command/src/conversions/into/duration.rs index a137efc549..285251890f 100644 --- a/crates/nu-command/src/conversions/into/duration.rs +++ b/crates/nu-command/src/conversions/into/duration.rs @@ -315,17 +315,17 @@ fn convert_str_from_unit_to_unit( ("yr", "yr") => Ok(val as f64), ("yr", "dec") => Ok(val as f64 / 10.0), - _ => Err(ShellError::CantConvertWithValue( - "string duration".to_string(), - "string duration".to_string(), - to_unit.to_string(), - span, - value_span, - Some( + _ => Err(ShellError::CantConvertWithValue { + to_type: "string duration".to_string(), + from_type: "string duration".to_string(), + details: to_unit.to_string(), + dst_span: span, + src_span: value_span, + help: Some( "supported units are ns, us, ms, sec, min, hr, day, wk, month, yr and dec" .to_string(), ), - )), + }), } } @@ -348,16 +348,16 @@ fn string_to_duration(s: &str, span: Span, value_span: Span) -> Result Value { fn int_from_string(a_string: &str, span: Span) -> Result { match a_string.trim().parse::() { Ok(n) => Ok(n.0 as i64), - Err(_) => Err(ShellError::CantConvert( - "int".into(), - "string".into(), + Err(_) => Err(ShellError::CantConvert { + to_type: "int".into(), + from_type: "string".into(), span, - None, - )), + help: None, + }), } } diff --git a/crates/nu-command/src/conversions/into/int.rs b/crates/nu-command/src/conversions/into/int.rs index e4375e8de5..1f1862402e 100644 --- a/crates/nu-command/src/conversions/into/int.rs +++ b/crates/nu-command/src/conversions/into/int.rs @@ -187,12 +187,12 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Ok(v) => v, _ => { return Value::Error { - error: ShellError::CantConvert( - "float".to_string(), - "integer".to_string(), + error: ShellError::CantConvert { + to_type: "float".to_string(), + from_type: "integer".to_string(), span, - None, - ), + help: None, + }, } } } @@ -277,12 +277,12 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value { Ok(n) => return Value::int(n, head), Err(e) => { return Value::Error { - error: ShellError::CantConvert( - "string".to_string(), - "int".to_string(), - head, - Some(e.to_string()), - ), + error: ShellError::CantConvert { + to_type: "string".to_string(), + from_type: "int".to_string(), + span: head, + help: Some(e.to_string()), + }, } } } @@ -305,7 +305,12 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value { match i64::from_str_radix(i.trim(), radix) { Ok(n) => Value::int(n, head), Err(_reason) => Value::Error { - error: ShellError::CantConvert("string".to_string(), "int".to_string(), head, None), + error: ShellError::CantConvert { + to_type: "string".to_string(), + from_type: "int".to_string(), + span: head, + help: None, + }, }, } } @@ -317,12 +322,12 @@ fn int_from_string(a_string: &str, span: Span) -> Result { let num = match i64::from_str_radix(b.trim_start_matches("0b"), 2) { Ok(n) => n, Err(_reason) => { - return Err(ShellError::CantConvert( - "int".to_string(), - "string".to_string(), + return Err(ShellError::CantConvert { + to_type: "int".to_string(), + from_type: "string".to_string(), span, - Some(r#"digits following "0b" can only be 0 or 1"#.to_string()), - )) + help: Some(r#"digits following "0b" can only be 0 or 1"#.to_string()), + }) } }; Ok(num) @@ -331,15 +336,15 @@ fn int_from_string(a_string: &str, span: Span) -> Result { let num = match i64::from_str_radix(h.trim_start_matches("0x"), 16) { Ok(n) => n, - Err(_reason) => return Err(ShellError::CantConvert( - "int".to_string(), - "string".to_string(), + Err(_reason) => return Err(ShellError::CantConvert { + to_type: "int".to_string(), + from_type: "string".to_string(), span, - Some( + help: Some( r#"hexadecimal digits following "0x" should be in 0-9, a-f, or A-F"# .to_string(), ), - )), + }), }; Ok(num) } @@ -347,12 +352,12 @@ fn int_from_string(a_string: &str, span: Span) -> Result { let num = match i64::from_str_radix(o.trim_start_matches("0o"), 8) { Ok(n) => n, Err(_reason) => { - return Err(ShellError::CantConvert( - "int".to_string(), - "string".to_string(), + return Err(ShellError::CantConvert { + to_type: "int".to_string(), + from_type: "string".to_string(), span, - Some(r#"octal digits following "0o" should be in 0-7"#.to_string()), - )) + help: Some(r#"octal digits following "0o" should be in 0-7"#.to_string()), + }) } }; Ok(num) @@ -361,14 +366,14 @@ fn int_from_string(a_string: &str, span: Span) -> Result { Ok(n) => Ok(n), Err(_) => match a_string.parse::() { Ok(f) => Ok(f as i64), - _ => Err(ShellError::CantConvert( - "int".to_string(), - "string".to_string(), + _ => Err(ShellError::CantConvert { + to_type: "int".to_string(), + from_type: "string".to_string(), span, - Some(format!( + help: Some(format!( r#"string "{trimmed}" does not represent a valid integer"# )), - )), + }), }, }, } diff --git a/crates/nu-command/src/conversions/into/string.rs b/crates/nu-command/src/conversions/into/string.rs index be61e6544b..b6ad99f724 100644 --- a/crates/nu-command/src/conversions/into/string.rs +++ b/crates/nu-command/src/conversions/into/string.rs @@ -247,28 +247,28 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { span: _, } => Value::Error { // Watch out for CantConvert's argument order - error: ShellError::CantConvert( - "string".into(), - "record".into(), + error: ShellError::CantConvert { + to_type: "string".into(), + from_type: "record".into(), span, - Some("try using the `to nuon` command".into()), - ), + help: Some("try using the `to nuon` command".into()), + }, }, Value::Binary { .. } => Value::Error { - error: ShellError::CantConvert( - "string".into(), - "binary".into(), + error: ShellError::CantConvert { + to_type: "string".into(), + from_type: "binary".into(), span, - Some("try using the `decode` command".into()), - ), + help: Some("try using the `decode` command".into()), + }, }, x => Value::Error { - error: ShellError::CantConvert( - String::from("string"), - x.get_type().to_string(), + error: ShellError::CantConvert { + to_type: String::from("string"), + from_type: x.get_type().to_string(), span, - None, - ), + help: None, + }, }, } } diff --git a/crates/nu-command/src/database/values/sqlite.rs b/crates/nu-command/src/database/values/sqlite.rs index 50d9482e01..dca57b1915 100644 --- a/crates/nu-command/src/database/values/sqlite.rs +++ b/crates/nu-command/src/database/values/sqlite.rs @@ -62,19 +62,19 @@ impl SQLiteDatabase { path: db.path.clone(), ctrlc: db.ctrlc.clone(), }), - None => Err(ShellError::CantConvert( - "database".into(), - "non-database".into(), + None => Err(ShellError::CantConvert { + to_type: "database".into(), + from_type: "non-database".into(), span, - None, - )), + help: None, + }), }, - x => Err(ShellError::CantConvert( - "database".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "database".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } @@ -309,7 +309,7 @@ impl CustomValue for SQLiteDatabase { fn follow_path_int(&self, _count: usize, span: Span) -> Result { // In theory we could support this, but tables don't have an especially well-defined order - Err(ShellError::IncompatiblePathAccess("SQLite databases do not support integer-indexed access. Try specifying a table name instead".into(), span)) + Err(ShellError::IncompatiblePathAccess { type_name: "SQLite databases do not support integer-indexed access. Try specifying a table name instead".into(), span }) } fn follow_path_string(&self, _column_name: String, span: Span) -> Result { diff --git a/crates/nu-command/src/dataframe/eager/with_column.rs b/crates/nu-command/src/dataframe/eager/with_column.rs index ad4ac6879b..09a7c977e0 100644 --- a/crates/nu-command/src/dataframe/eager/with_column.rs +++ b/crates/nu-command/src/dataframe/eager/with_column.rs @@ -109,12 +109,12 @@ impl Command for WithColumn { let df = NuDataFrame::try_from_value(value)?; command_eager(engine_state, stack, call, df) } else { - Err(ShellError::CantConvert( - "lazy or eager dataframe".into(), - value.get_type().to_string(), - value.span()?, - None, - )) + Err(ShellError::CantConvert { + to_type: "lazy or eager dataframe".into(), + from_type: value.get_type().to_string(), + span: value.span()?, + help: None, + }) } } } diff --git a/crates/nu-command/src/dataframe/values/nu_dataframe/between_values.rs b/crates/nu-command/src/dataframe/values/nu_dataframe/between_values.rs index 020b94d333..9e53765d50 100644 --- a/crates/nu-command/src/dataframe/values/nu_dataframe/between_values.rs +++ b/crates/nu-command/src/dataframe/values/nu_dataframe/between_values.rs @@ -270,14 +270,14 @@ pub(super) fn compute_series_single_value( Operator::Math(Math::Divide) => match &right { Value::Int { val, span } => { if *val == 0 { - Err(ShellError::DivisionByZero(*span)) + Err(ShellError::DivisionByZero { span: *span }) } else { compute_series_i64(&lhs, *val, >::div, lhs_span) } } Value::Float { val, span } => { if val.is_zero() { - Err(ShellError::DivisionByZero(*span)) + Err(ShellError::DivisionByZero { span: *span }) } else { compute_series_decimal(&lhs, *val, >::div, lhs_span) } diff --git a/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs b/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs index 3302f4d1f6..2823e5ae70 100644 --- a/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs @@ -240,12 +240,12 @@ impl NuDataFrame { let df = lazy.collect(span)?; Ok(df) } else { - Err(ShellError::CantConvert( - "lazy or eager dataframe".into(), - value.get_type().to_string(), - value.span()?, - None, - )) + Err(ShellError::CantConvert { + to_type: "lazy or eager dataframe".into(), + from_type: value.get_type().to_string(), + span: value.span()?, + help: None, + }) } } @@ -256,19 +256,19 @@ impl NuDataFrame { df: df.df.clone(), from_lazy: false, }), - None => Err(ShellError::CantConvert( - "dataframe".into(), - "non-dataframe".into(), + None => Err(ShellError::CantConvert { + to_type: "dataframe".into(), + from_type: "non-dataframe".into(), span, - None, - )), + help: None, + }), }, - x => Err(ShellError::CantConvert( - "dataframe".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "dataframe".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } @@ -343,7 +343,7 @@ impl NuDataFrame { let column = conversion::create_column(&series, row, row + 1, span)?; if column.len() == 0 { - Err(ShellError::AccessEmptyContent(span)) + Err(ShellError::AccessEmptyContent { span }) } else { let value = column .into_iter() diff --git a/crates/nu-command/src/dataframe/values/nu_expression/mod.rs b/crates/nu-command/src/dataframe/values/nu_expression/mod.rs index c213a29735..d5fcfb809f 100644 --- a/crates/nu-command/src/dataframe/values/nu_expression/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_expression/mod.rs @@ -72,23 +72,23 @@ impl NuExpression { match value { Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { Some(expr) => Ok(NuExpression(expr.0.clone())), - None => Err(ShellError::CantConvert( - "lazy expression".into(), - "non-dataframe".into(), + None => Err(ShellError::CantConvert { + to_type: "lazy expression".into(), + from_type: "non-dataframe".into(), span, - None, - )), + help: None, + }), }, Value::String { val, .. } => Ok(val.lit().into()), Value::Int { val, .. } => Ok(val.lit().into()), Value::Bool { val, .. } => Ok(val.lit().into()), Value::Float { val, .. } => Ok(val.lit().into()), - x => Err(ShellError::CantConvert( - "lazy expression".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "lazy expression".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } @@ -160,12 +160,12 @@ impl ExtractedExpr { .map(Self::extract_exprs) .collect::, ShellError>>() .map(ExtractedExpr::List), - x => Err(ShellError::CantConvert( - "expression".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "expression".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } } diff --git a/crates/nu-command/src/dataframe/values/nu_lazyframe/mod.rs b/crates/nu-command/src/dataframe/values/nu_lazyframe/mod.rs index 5d45543fcc..ff637bb605 100644 --- a/crates/nu-command/src/dataframe/values/nu_lazyframe/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_lazyframe/mod.rs @@ -132,12 +132,12 @@ impl NuLazyFrame { let df = NuDataFrame::try_from_value(value)?; Ok(NuLazyFrame::from_dataframe(df)) } else { - Err(ShellError::CantConvert( - "lazy or eager dataframe".into(), - value.get_type().to_string(), - value.span()?, - None, - )) + Err(ShellError::CantConvert { + to_type: "lazy or eager dataframe".into(), + from_type: value.get_type().to_string(), + span: value.span()?, + help: None, + }) } } @@ -154,19 +154,19 @@ impl NuLazyFrame { from_eager: false, schema: None, }), - None => Err(ShellError::CantConvert( - "lazy frame".into(), - "non-dataframe".into(), + None => Err(ShellError::CantConvert { + to_type: "lazy frame".into(), + from_type: "non-dataframe".into(), span, - None, - )), + help: None, + }), }, - x => Err(ShellError::CantConvert( - "lazy frame".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "lazy frame".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } diff --git a/crates/nu-command/src/dataframe/values/nu_lazygroupby/mod.rs b/crates/nu-command/src/dataframe/values/nu_lazygroupby/mod.rs index 4bfd4e5bef..9d2efd15a6 100644 --- a/crates/nu-command/src/dataframe/values/nu_lazygroupby/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_lazygroupby/mod.rs @@ -93,20 +93,20 @@ impl NuLazyGroupBy { schema: group.schema.clone(), from_eager: group.from_eager, }), - None => Err(ShellError::CantConvert( - "lazy groupby".into(), - "custom value".into(), + None => Err(ShellError::CantConvert { + to_type: "lazy groupby".into(), + from_type: "custom value".into(), span, - None, - )), + help: None, + }), } } - x => Err(ShellError::CantConvert( - "lazy groupby".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "lazy groupby".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } diff --git a/crates/nu-command/src/dataframe/values/nu_when/mod.rs b/crates/nu-command/src/dataframe/values/nu_when/mod.rs index 3cacc7cf54..a1fe747e5e 100644 --- a/crates/nu-command/src/dataframe/values/nu_when/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_when/mod.rs @@ -61,19 +61,19 @@ impl NuWhen { match value { Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { Some(expr) => Ok(expr.clone()), - None => Err(ShellError::CantConvert( - "when expression".into(), - "non when expression".into(), + None => Err(ShellError::CantConvert { + to_type: "when expression".into(), + from_type: "non when expression".into(), span, - None, - )), + help: None, + }), }, - x => Err(ShellError::CantConvert( - "when expression".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "when expression".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } } diff --git a/crates/nu-command/src/env/let_env.rs b/crates/nu-command/src/env/let_env.rs index e3ee9ae32c..6b9bc7b4c8 100644 --- a/crates/nu-command/src/env/let_env.rs +++ b/crates/nu-command/src/env/let_env.rs @@ -52,10 +52,10 @@ impl Command for LetEnv { .into_value(call.head); if env_var.item == "FILE_PWD" || env_var.item == "PWD" { - return Err(ShellError::AutomaticEnvVarSetManually( - env_var.item, - env_var.span, - )); + return Err(ShellError::AutomaticEnvVarSetManually { + envvar_name: env_var.item, + span: env_var.span, + }); } else { stack.add_env_var(env_var.item, rhs); } diff --git a/crates/nu-command/src/env/load_env.rs b/crates/nu-command/src/env/load_env.rs index 4040a5b1dc..485cd8e51b 100644 --- a/crates/nu-command/src/env/load_env.rs +++ b/crates/nu-command/src/env/load_env.rs @@ -43,11 +43,17 @@ impl Command for LoadEnv { Some((cols, vals)) => { for (env_var, rhs) in cols.into_iter().zip(vals) { if env_var == "FILE_PWD" { - return Err(ShellError::AutomaticEnvVarSetManually(env_var, call.head)); + return Err(ShellError::AutomaticEnvVarSetManually { + envvar_name: env_var, + span: call.head, + }); } if env_var == "PWD" { - return Err(ShellError::AutomaticEnvVarSetManually(env_var, call.head)); + return Err(ShellError::AutomaticEnvVarSetManually { + envvar_name: env_var, + span: call.head, + }); } else { stack.add_env_var(env_var, rhs); } @@ -58,7 +64,10 @@ impl Command for LoadEnv { PipelineData::Value(Value::Record { cols, vals, .. }, ..) => { for (env_var, rhs) in cols.into_iter().zip(vals) { if env_var == "FILE_PWD" { - return Err(ShellError::AutomaticEnvVarSetManually(env_var, call.head)); + return Err(ShellError::AutomaticEnvVarSetManually { + envvar_name: env_var, + span: call.head, + }); } if env_var == "PWD" { diff --git a/crates/nu-command/src/env/with_env.rs b/crates/nu-command/src/env/with_env.rs index a0391863a1..78ab778092 100644 --- a/crates/nu-command/src/env/with_env.rs +++ b/crates/nu-command/src/env/with_env.rs @@ -100,14 +100,15 @@ fn with_env( } } x => { - return Err(ShellError::CantConvert( - "string list or single row".into(), - x.get_type().to_string(), - call.positional_nth(1) + return Err(ShellError::CantConvert { + to_type: "string list or single row".into(), + from_type: x.get_type().to_string(), + span: call + .positional_nth(1) .expect("already checked through .req") .span, - None, - )); + help: None, + }); } } } else { @@ -127,14 +128,15 @@ fn with_env( } } x => { - return Err(ShellError::CantConvert( - "string list or single row".into(), - x.get_type().to_string(), - call.positional_nth(1) + return Err(ShellError::CantConvert { + to_type: "string list or single row".into(), + from_type: x.get_type().to_string(), + span: call + .positional_nth(1) .expect("already checked through .req") .span, - None, - )); + help: None, + }); } }; diff --git a/crates/nu-command/src/filesystem/save.rs b/crates/nu-command/src/filesystem/save.rs index 1322fb685c..e7026d26d7 100644 --- a/crates/nu-command/src/filesystem/save.rs +++ b/crates/nu-command/src/filesystem/save.rs @@ -101,12 +101,10 @@ impl Command for Save { let res = stream_to_file(stream, file, span, progress); if let Some(h) = handler { - h.join().map_err(|err| { - ShellError::ExternalCommand( - "Fail to receive external commands stderr message".to_string(), - format!("{err:?}"), - span, - ) + h.join().map_err(|err| ShellError::ExternalCommand { + label: "Fail to receive external commands stderr message".to_string(), + help: format!("{err:?}"), + span, })??; res } else { diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs index 46e8b92bc8..b22ccaccef 100644 --- a/crates/nu-command/src/filters/first.rs +++ b/crates/nu-command/src/filters/first.rs @@ -110,7 +110,7 @@ fn first_helper( Value::List { vals, .. } => { if return_single_element { if vals.is_empty() { - Err(ShellError::AccessEmptyContent(head)) + Err(ShellError::AccessEmptyContent { span: head }) } else { Ok(vals[0].clone().into_pipeline_data()) } @@ -154,7 +154,7 @@ fn first_helper( if let Some(v) = ls.next() { Ok(v.into_pipeline_data()) } else { - Err(ShellError::AccessEmptyContent(head)) + Err(ShellError::AccessEmptyContent { span: head }) } } else { Ok(ls diff --git a/crates/nu-command/src/filters/group_by.rs b/crates/nu-command/src/filters/group_by.rs index c352920428..18468f0ccc 100644 --- a/crates/nu-command/src/filters/group_by.rs +++ b/crates/nu-command/src/filters/group_by.rs @@ -248,11 +248,11 @@ pub fn group( }; match row.get_data_by_key(&column_name.item) { Some(group_key) => Ok(group_key.as_string()?), - None => Err(ShellError::CantFindColumn( - column_name.item.to_string(), - column_name.span, - row.expect_span(), - )), + None => Err(ShellError::CantFindColumn { + col_name: column_name.item.to_string(), + span: column_name.span, + src_span: row.expect_span(), + }), } }); @@ -263,9 +263,9 @@ pub fn group( data_group(values, &Some(block), name) } - Grouper::ByBlock => Err(ShellError::NushellFailed( - "Block not implemented: This should never happen.".into(), - )), + Grouper::ByBlock => Err(ShellError::NushellFailed { + msg: "Block not implemented: This should never happen.".into(), + }), } } diff --git a/crates/nu-command/src/filters/move_.rs b/crates/nu-command/src/filters/move_.rs index 1bc2da3e4e..e67337d9ff 100644 --- a/crates/nu-command/src/filters/move_.rs +++ b/crates/nu-command/src/filters/move_.rs @@ -262,11 +262,11 @@ fn move_record_columns( out_cols.push(col.into()); out_vals.push(val.clone()); } else { - return Err(ShellError::NushellFailedSpanned( - "Error indexing input columns".to_string(), - "originates from here".to_string(), + return Err(ShellError::NushellFailedSpanned { + msg: "Error indexing input columns".to_string(), + label: "originates from here".to_string(), span, - )); + }); } } } @@ -276,11 +276,11 @@ fn move_record_columns( out_cols.push(col.into()); out_vals.push(val.clone()); } else { - return Err(ShellError::NushellFailedSpanned( - "Error indexing input columns".to_string(), - "originates from here".to_string(), + return Err(ShellError::NushellFailedSpanned { + msg: "Error indexing input columns".to_string(), + label: "originates from here".to_string(), span, - )); + }); } } diff --git a/crates/nu-command/src/filters/split_by.rs b/crates/nu-command/src/filters/split_by.rs index 4b7d368b09..15fffa354e 100644 --- a/crates/nu-command/src/filters/split_by.rs +++ b/crates/nu-command/src/filters/split_by.rs @@ -164,11 +164,11 @@ pub fn split( Box::new( move |_, row: &Value| match row.get_data_by_key(&column_name.item) { Some(group_key) => Ok(group_key.as_string()?), - None => Err(ShellError::CantFindColumn( - column_name.item.to_string(), - column_name.span, - row.span().unwrap_or(column_name.span), - )), + None => Err(ShellError::CantFindColumn { + col_name: column_name.item.to_string(), + span: column_name.span, + src_span: row.span().unwrap_or(column_name.span), + }), }, ); diff --git a/crates/nu-command/src/filters/uniq_by.rs b/crates/nu-command/src/filters/uniq_by.rs index 95bd1086f3..0c64b951a9 100644 --- a/crates/nu-command/src/filters/uniq_by.rs +++ b/crates/nu-command/src/filters/uniq_by.rs @@ -135,7 +135,11 @@ fn validate(vec: Vec, columns: &Vec, span: Span) -> Result<(), Sh } if let Some(nonexistent) = nonexistent_column(columns.clone(), cols.to_vec()) { - return Err(ShellError::CantFindColumn(nonexistent, span, *val_span)); + return Err(ShellError::CantFindColumn { + col_name: nonexistent, + span, + src_span: *val_span, + }); } } diff --git a/crates/nu-command/src/filters/update.rs b/crates/nu-command/src/filters/update.rs index 3919692e44..1db469a2a7 100644 --- a/crates/nu-command/src/filters/update.rs +++ b/crates/nu-command/src/filters/update.rs @@ -151,9 +151,12 @@ fn update( if let Some(v) = input.next() { pre_elems.push(v); } else if idx == 0 { - return Err(ShellError::AccessEmptyContent(*span)); + return Err(ShellError::AccessEmptyContent { span: *span }); } else { - return Err(ShellError::AccessBeyondEnd(idx - 1, *span)); + return Err(ShellError::AccessBeyondEnd { + max_idx: idx - 1, + span: *span, + }); } } diff --git a/crates/nu-command/src/filters/upsert.rs b/crates/nu-command/src/filters/upsert.rs index eda402618d..30729fae5a 100644 --- a/crates/nu-command/src/filters/upsert.rs +++ b/crates/nu-command/src/filters/upsert.rs @@ -173,7 +173,10 @@ fn upsert( if let Some(v) = input.next() { pre_elems.push(v); } else { - return Err(ShellError::AccessBeyondEnd(idx, *span)); + return Err(ShellError::AccessBeyondEnd { + max_idx: idx, + span: *span, + }); } } diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index 9e3392e741..031ad07bcd 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -119,12 +119,12 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value { nu_json::Value::U64(u) => { if *u > i64::MAX as u64 { Value::Error { - error: ShellError::CantConvert( - "i64 sized integer".into(), - "value larger than i64".into(), + error: ShellError::CantConvert { + to_type: "i64 sized integer".into(), + from_type: "value larger than i64".into(), span, - None, - ), + help: None, + }, } } else { Value::Int { @@ -182,12 +182,12 @@ fn convert_string_to_value(string_input: String, span: Span) -> Result Err(ShellError::CantConvert( - format!("structured json data ({x})"), - "string".into(), + x => Err(ShellError::CantConvert { + to_type: format!("structured json data ({x})"), + from_type: "string".into(), span, - None, - )), + help: None, + }), }, } } diff --git a/crates/nu-command/src/formats/from/toml.rs b/crates/nu-command/src/formats/from/toml.rs index 5395fa5d74..0fc5b7c2a2 100644 --- a/crates/nu-command/src/formats/from/toml.rs +++ b/crates/nu-command/src/formats/from/toml.rs @@ -106,12 +106,12 @@ pub fn convert_string_to_value(string_input: String, span: Span) -> Result Ok(convert_toml_to_value(&value, span)), - Err(err) => Err(ShellError::CantConvert( - "structured toml data".into(), - "string".into(), + Err(err) => Err(ShellError::CantConvert { + to_type: "structured toml data".into(), + from_type: "string".into(), span, - Some(err.to_string()), - )), + help: Some(err.to_string()), + }), } } diff --git a/crates/nu-command/src/formats/to/delimited.rs b/crates/nu-command/src/formats/to/delimited.rs index f66b4776cd..9e9b16ff7f 100644 --- a/crates/nu-command/src/formats/to/delimited.rs +++ b/crates/nu-command/src/formats/to/delimited.rs @@ -95,7 +95,12 @@ fn writer_to_string(writer: Writer>) -> Result> { } fn make_conversion_error(type_from: &str, span: &Span) -> ShellError { - ShellError::CantConvert(type_from.to_string(), "string".to_string(), *span, None) + ShellError::CantConvert { + to_type: type_from.to_string(), + from_type: "string".to_string(), + span: *span, + help: None, + } } fn to_string_tagged_value( @@ -174,12 +179,12 @@ pub fn to_delimited_data( } Ok(x) } - Err(_) => Err(ShellError::CantConvert( - format_name.into(), - value.get_type().to_string(), - value.span().unwrap_or(span), - None, - )), + Err(_) => Err(ShellError::CantConvert { + to_type: format_name.into(), + from_type: value.get_type().to_string(), + span: value.span().unwrap_or(span), + help: None, + }), }?; Ok(Value::string(output, span).into_pipeline_data()) } diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 46cd0b92a2..72cbb8519e 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -70,12 +70,12 @@ impl Command for ToJson { } .into_pipeline_data()), _ => Ok(Value::Error { - error: ShellError::CantConvert( - "JSON".into(), - value.get_type().to_string(), + error: ShellError::CantConvert { + to_type: "JSON".into(), + from_type: value.get_type().to_string(), span, - None, - ), + help: None, + }, } .into_pipeline_data()), } diff --git a/crates/nu-command/src/formats/to/toml.rs b/crates/nu-command/src/formats/to/toml.rs index ec47f20167..4738dd379c 100644 --- a/crates/nu-command/src/formats/to/toml.rs +++ b/crates/nu-command/src/formats/to/toml.rs @@ -118,7 +118,12 @@ fn toml_into_pipeline_data( } .into_pipeline_data()), _ => Ok(Value::Error { - error: ShellError::CantConvert("TOML".into(), value_type.to_string(), span, None), + error: ShellError::CantConvert { + to_type: "TOML".into(), + from_type: value_type.to_string(), + span, + help: None, + }, } .into_pipeline_data()), } diff --git a/crates/nu-command/src/formats/to/xml.rs b/crates/nu-command/src/formats/to/xml.rs index 9444f4500b..1d01554657 100644 --- a/crates/nu-command/src/formats/to/xml.rs +++ b/crates/nu-command/src/formats/to/xml.rs @@ -185,12 +185,12 @@ fn to_xml( }; Ok(Value::string(s, head).into_pipeline_data()) } - Err(_) => Err(ShellError::CantConvert( - "XML".into(), - value_type.to_string(), - head, - None, - )), + Err(_) => Err(ShellError::CantConvert { + to_type: "XML".into(), + from_type: value_type.to_string(), + span: head, + help: None, + }), } } diff --git a/crates/nu-command/src/formats/to/yaml.rs b/crates/nu-command/src/formats/to/yaml.rs index ec2e8fbe2a..a8ccd72fea 100644 --- a/crates/nu-command/src/formats/to/yaml.rs +++ b/crates/nu-command/src/formats/to/yaml.rs @@ -111,7 +111,12 @@ fn to_yaml(input: PipelineData, head: Span) -> Result } .into_pipeline_data()), _ => Ok(Value::Error { - error: ShellError::CantConvert("YAML".into(), value.get_type().to_string(), head, None), + error: ShellError::CantConvert { + to_type: "YAML".into(), + from_type: value.get_type().to_string(), + span: head, + help: None, + }, } .into_pipeline_data()), } diff --git a/crates/nu-command/src/network/http/client.rs b/crates/nu-command/src/network/http/client.rs index 27b1e67888..c09cdb3200 100644 --- a/crates/nu-command/src/network/http/client.rs +++ b/crates/nu-command/src/network/http/client.rs @@ -241,12 +241,12 @@ pub fn request_add_custom_headers( } x => { - return Err(ShellError::CantConvert( - "string list or single row".into(), - x.get_type().to_string(), - headers.span().unwrap_or_else(|_| Span::new(0, 0)), - None, - )); + return Err(ShellError::CantConvert { + to_type: "string list or single row".into(), + from_type: x.get_type().to_string(), + span: headers.span().unwrap_or_else(|_| Span::new(0, 0)), + help: None, + }); } } } else { @@ -260,12 +260,12 @@ pub fn request_add_custom_headers( } x => { - return Err(ShellError::CantConvert( - "string list or single row".into(), - x.get_type().to_string(), - headers.span().unwrap_or_else(|_| Span::new(0, 0)), - None, - )); + return Err(ShellError::CantConvert { + to_type: "string list or single row".into(), + from_type: x.get_type().to_string(), + span: headers.span().unwrap_or_else(|_| Span::new(0, 0)), + help: None, + }); } }; diff --git a/crates/nu-command/src/network/url/build_query.rs b/crates/nu-command/src/network/url/build_query.rs index a65d13bb35..78f44ab7c9 100644 --- a/crates/nu-command/src/network/url/build_query.rs +++ b/crates/nu-command/src/network/url/build_query.rs @@ -89,12 +89,12 @@ fn to_url(input: PipelineData, head: Span) -> Result { match serde_urlencoded::to_string(row_vec) { Ok(s) => Ok(s), - _ => Err(ShellError::CantConvert( - "URL".into(), - value.get_type().to_string(), - head, - None, - )), + _ => Err(ShellError::CantConvert { + to_type: "URL".into(), + from_type: value.get_type().to_string(), + span: head, + help: None, + }), } } // Propagate existing errors diff --git a/crates/nu-command/src/path/relative_to.rs b/crates/nu-command/src/path/relative_to.rs index ab9c8e9e40..8c99fe9aa5 100644 --- a/crates/nu-command/src/path/relative_to.rs +++ b/crates/nu-command/src/path/relative_to.rs @@ -128,7 +128,12 @@ fn relative_to(path: &Path, span: Span, args: &Arguments) -> Value { match lhs.strip_prefix(&rhs) { Ok(p) => Value::string(p.to_string_lossy(), span), Err(e) => Value::Error { - error: ShellError::CantConvert(e.to_string(), "string".into(), span, None), + error: ShellError::CantConvert { + to_type: e.to_string(), + from_type: "string".into(), + span, + help: None, + }, }, } } diff --git a/crates/nu-command/src/random/bool.rs b/crates/nu-command/src/random/bool.rs index 419ea59ef3..e686fbee67 100644 --- a/crates/nu-command/src/random/bool.rs +++ b/crates/nu-command/src/random/bool.rs @@ -77,7 +77,7 @@ fn bool( let probability_is_valid = (0.0..=1.0).contains(&probability); if !probability_is_valid { - return Err(ShellError::InvalidProbability(prob.span)); + return Err(ShellError::InvalidProbability { span: prob.span }); } } diff --git a/crates/nu-command/src/shells/g.rs b/crates/nu-command/src/shells/g.rs index ed78a13457..a5eb1b7c5a 100644 --- a/crates/nu-command/src/shells/g.rs +++ b/crates/nu-command/src/shells/g.rs @@ -50,7 +50,9 @@ impl Command for GotoShell { let n = shell_span .item .parse::() - .map_err(|_| ShellError::NotFound(shell_span.span))?; + .map_err(|_| ShellError::NotFound { + span: shell_span.span, + })?; switch_shell(engine_state, stack, call, shell_span.span, SwitchTo::Nth(n)) } diff --git a/crates/nu-command/src/shells/mod.rs b/crates/nu-command/src/shells/mod.rs index 8e17a96d9c..19f76d9960 100644 --- a/crates/nu-command/src/shells/mod.rs +++ b/crates/nu-command/src/shells/mod.rs @@ -89,7 +89,7 @@ fn switch_shell( let new_path = shells .get(new_shell) - .ok_or(ShellError::NotFound(span))? + .ok_or(ShellError::NotFound { span })? .to_owned(); stack.add_env_var( diff --git a/crates/nu-command/src/sort_utils.rs b/crates/nu-command/src/sort_utils.rs index b8313d5cf4..fca2b49135 100644 --- a/crates/nu-command/src/sort_utils.rs +++ b/crates/nu-command/src/sort_utils.rs @@ -89,7 +89,11 @@ pub fn sort( } if let Some(nonexistent) = nonexistent_column(sort_columns.clone(), cols.to_vec()) { - return Err(ShellError::CantFindColumn(nonexistent, span, *val_span)); + return Err(ShellError::CantFindColumn { + col_name: nonexistent, + span, + src_span: *val_span, + }); } // check to make sure each value in each column in the record diff --git a/crates/nu-command/src/system/complete.rs b/crates/nu-command/src/system/complete.rs index 2f1f61a309..016b134884 100644 --- a/crates/nu-command/src/system/complete.rs +++ b/crates/nu-command/src/system/complete.rs @@ -95,12 +95,10 @@ impl Command for Complete { if let Some((handler, stderr_span)) = stderr_handler { cols.push("stderr".to_string()); - let res = handler.join().map_err(|err| { - ShellError::ExternalCommand( - "Fail to receive external commands stderr message".to_string(), - format!("{err:?}"), - stderr_span, - ) + let res = handler.join().map_err(|err| ShellError::ExternalCommand { + label: "Fail to receive external commands stderr message".to_string(), + help: format!("{err:?}"), + span: stderr_span, })??; vals.push(res) }; diff --git a/crates/nu-command/src/system/nu_check.rs b/crates/nu-command/src/system/nu_check.rs index 37f48eaed9..2566d6c5d6 100644 --- a/crates/nu-command/src/system/nu_check.rs +++ b/crates/nu-command/src/system/nu_check.rs @@ -291,7 +291,7 @@ fn heuristic_parse_file( Err(ShellError::IOError("Can not read input".to_string())) } } else { - Err(ShellError::NotFound(call.head)) + Err(ShellError::NotFound { span: call.head }) } } @@ -378,7 +378,7 @@ fn parse_file_script( Err(ShellError::IOError("Can not read path".to_string())) } } else { - Err(ShellError::NotFound(call.head)) + Err(ShellError::NotFound { span: call.head }) } } @@ -396,6 +396,6 @@ fn parse_file_module( Err(ShellError::IOError("Can not read path".to_string())) } } else { - Err(ShellError::NotFound(call.head)) + Err(ShellError::NotFound { span: call.head }) } } diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index c941843ba8..7107c1de69 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -106,12 +106,10 @@ pub fn create_external_command( value .as_string() .map(|item| Spanned { item, span }) - .map_err(|_| { - ShellError::ExternalCommand( - format!("Cannot convert {} to a string", value.get_type()), - "All arguments to an external command need to be string-compatible".into(), - span, - ) + .map_err(|_| ShellError::ExternalCommand { + label: format!("Cannot convert {} to a string", value.get_type()), + help: "All arguments to an external command need to be string-compatible".into(), + span, }) } @@ -326,18 +324,18 @@ impl ExternalCommand { } }; - Err(ShellError::ExternalCommand( + Err(ShellError::ExternalCommand { label, - err.to_string(), - self.name.span, - )) + help: err.to_string(), + span: self.name.span, + }) } // otherwise, a default error message - _ => Err(ShellError::ExternalCommand( - "can't run executable".into(), - err.to_string(), - self.name.span, - )), + _ => Err(ShellError::ExternalCommand { + label: "can't run executable".into(), + help: err.to_string(), + span: self.name.span, + }), } } Ok(mut child) => { @@ -408,23 +406,15 @@ impl ExternalCommand { .spawn(move || { if redirect_stdout { let stdout = stdout.ok_or_else(|| { - ShellError::ExternalCommand( - "Error taking stdout from external".to_string(), - "Redirects need access to stdout of an external command" - .to_string(), - span, - ) + ShellError::ExternalCommand { label: "Error taking stdout from external".to_string(), help: "Redirects need access to stdout of an external command" + .to_string(), span } })?; read_and_redirect_message(stdout, stdout_tx, ctrlc) } match child.as_mut().wait() { - Err(err) => Err(ShellError::ExternalCommand( - "External command exited with error".into(), - err.to_string(), - span, - )), + Err(err) => Err(ShellError::ExternalCommand { label: "External command exited with error".into(), help: err.to_string(), span }), Ok(x) => { #[cfg(unix)] { @@ -455,11 +445,7 @@ impl ExternalCommand { )) ); let _ = exit_code_tx.send(Value::Error { - error: ShellError::ExternalCommand( - "core dumped".to_string(), - format!("{cause}: child process '{commandname}' core dumped"), - head, - ), + error: ShellError::ExternalCommand { label: "core dumped".to_string(), help: format!("{cause}: child process '{commandname}' core dumped"), span: head }, }); return Ok(()); } @@ -481,13 +467,11 @@ impl ExternalCommand { thread::Builder::new() .name("stderr redirector".to_string()) .spawn(move || { - let stderr = stderr.ok_or_else(|| { - ShellError::ExternalCommand( - "Error taking stderr from external".to_string(), - "Redirects need access to stderr of an external command" - .to_string(), - span, - ) + let stderr = stderr.ok_or_else(|| ShellError::ExternalCommand { + label: "Error taking stderr from external".to_string(), + help: "Redirects need access to stderr of an external command" + .to_string(), + span, })?; read_and_redirect_message(stderr, stderr_tx, stderr_ctrlc); diff --git a/crates/nu-engine/src/call_ext.rs b/crates/nu-engine/src/call_ext.rs index 615a15161d..7bdab98d8d 100644 --- a/crates/nu-engine/src/call_ext.rs +++ b/crates/nu-engine/src/call_ext.rs @@ -98,12 +98,12 @@ impl CallExt for Call { let result = eval_expression(engine_state, stack, expr)?; FromValue::from_value(&result) } else if self.positional_len() == 0 { - Err(ShellError::AccessEmptyContent(self.head)) + Err(ShellError::AccessEmptyContent { span: self.head }) } else { - Err(ShellError::AccessBeyondEnd( - self.positional_len() - 1, - self.head, - )) + Err(ShellError::AccessBeyondEnd { + max_idx: self.positional_len() - 1, + span: self.head, + }) } } @@ -117,12 +117,12 @@ impl CallExt for Call { let result = eval_expression(engine_state, stack, expr)?; FromValue::from_value(&result) } else if self.parser_info.is_empty() { - Err(ShellError::AccessEmptyContent(self.head)) + Err(ShellError::AccessEmptyContent { span: self.head }) } else { - Err(ShellError::AccessBeyondEnd( - self.parser_info.len() - 1, - self.head, - )) + Err(ShellError::AccessBeyondEnd { + max_idx: self.parser_info.len() - 1, + span: self.head, + }) } } } diff --git a/crates/nu-engine/src/env.rs b/crates/nu-engine/src/env.rs index 50b73a8a3e..ed91fe6ed7 100644 --- a/crates/nu-engine/src/env.rs +++ b/crates/nu-engine/src/env.rs @@ -77,18 +77,12 @@ pub fn convert_env_values(engine_state: &mut EngineState, stack: &Stack) -> Opti } } else { error = error.or_else(|| { - Some(ShellError::NushellFailedHelp( - "Last active overlay not found in permanent state.".into(), - "This error happened during the conversion of environment variables from strings to Nushell values.".into(), - )) + Some(ShellError::NushellFailedHelp { msg: "Last active overlay not found in permanent state.".into(), help: "This error happened during the conversion of environment variables from strings to Nushell values.".into() }) }); } } else { error = error.or_else(|| { - Some(ShellError::NushellFailedHelp( - "Last active overlay not found in stack.".into(), - "This error happened during the conversion of environment variables from strings to Nushell values.".into(), - )) + Some(ShellError::NushellFailedHelp { msg: "Last active overlay not found in stack.".into(), help: "This error happened during the conversion of environment variables from strings to Nushell values.".into() }) }); } @@ -122,22 +116,22 @@ pub fn env_to_string( match std::env::join_paths(paths) { Ok(p) => Ok(p.to_string_lossy().to_string()), - Err(_) => Err(ShellError::EnvVarNotAString( - env_name.to_string(), - value.span()?, - )), + Err(_) => Err(ShellError::EnvVarNotAString { + envvar_name: env_name.to_string(), + span: value.span()?, + }), } } - _ => Err(ShellError::EnvVarNotAString( - env_name.to_string(), - value.span()?, - )), + _ => Err(ShellError::EnvVarNotAString { + envvar_name: env_name.to_string(), + span: value.span()?, + }), } } else { - Err(ShellError::EnvVarNotAString( - env_name.to_string(), - value.span()?, - )) + Err(ShellError::EnvVarNotAString { + envvar_name: env_name.to_string(), + span: value.span()?, + }) } } }, @@ -156,7 +150,7 @@ pub fn env_to_strings( Ok(val_str) => { env_vars_str.insert(env_name, val_str); } - Err(ShellError::EnvVarNotAString(..)) => {} // ignore non-string values + Err(ShellError::EnvVarNotAString { .. }) => {} // ignore non-string values Err(e) => return Err(e), } } @@ -214,16 +208,16 @@ pub fn path_str( #[cfg(windows)] match stack.get_env_var(engine_state, ENV_PATH_NAME_SECONDARY) { Some(v) => Ok((ENV_PATH_NAME_SECONDARY, v)), - None => Err(ShellError::EnvVarNotFoundAtRuntime( - ENV_PATH_NAME_SECONDARY.to_string(), + None => Err(ShellError::EnvVarNotFoundAtRuntime { + envvar_name: ENV_PATH_NAME_SECONDARY.to_string(), span, - )), + }), } #[cfg(not(windows))] - Err(ShellError::EnvVarNotFoundAtRuntime( - ENV_PATH_NAME.to_string(), + Err(ShellError::EnvVarNotFoundAtRuntime { + envvar_name: ENV_PATH_NAME.to_string(), span, - )) + }) } }?; diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index a12a668f27..0b33e884d4 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -197,7 +197,7 @@ fn eval_external( ) -> Result { let decl_id = engine_state .find_decl("run-external".as_bytes(), &[]) - .ok_or(ShellError::ExternalNotSupported(head.span))?; + .ok_or(ShellError::ExternalNotSupported { span: head.span })?; let command = engine_state.get_decl(decl_id); @@ -260,12 +260,12 @@ pub fn eval_expression( }), Expr::ValueWithUnit(e, unit) => match eval_expression(engine_state, stack, e)? { Value::Int { val, .. } => Ok(compute(val, unit.item, unit.span)), - x => Err(ShellError::CantConvert( - "unit value".into(), - x.get_type().to_string(), - e.span, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "unit value".into(), + from_type: x.get_type().to_string(), + span: e.span, + help: None, + }), }, Expr::Range(from, next, to, operator) => { let from = if let Some(f) = from { @@ -473,9 +473,9 @@ pub fn eval_expression( lhs.upsert_data_at_cell_path(&cell_path.tail, rhs)?; if is_env { if cell_path.tail.is_empty() { - return Err(ShellError::CannotReplaceEnv( - cell_path.head.span, - )); + return Err(ShellError::CannotReplaceEnv { + span: cell_path.head.span, + }); } // The special $env treatment: for something like $env.config.history.max_size = 2000, @@ -1251,11 +1251,11 @@ fn check_subexp_substitution(mut input: PipelineData) -> Result stderr_stream.into_string().map(|s| s.item)?, }; if failed_to_run { - Err(ShellError::ExternalCommand( - "External command failed".to_string(), - stderr_msg, + Err(ShellError::ExternalCommand { + label: "External command failed".to_string(), + help: stderr_msg, span, - )) + }) } else { // we've captured stderr message, but it's running success. // So we need to re-print stderr message out. diff --git a/crates/nu-parser/src/known_external.rs b/crates/nu-parser/src/known_external.rs index 4fad4bf777..83a1769225 100644 --- a/crates/nu-parser/src/known_external.rs +++ b/crates/nu-parser/src/known_external.rs @@ -45,7 +45,7 @@ impl Command for KnownExternal { let head_span = call.head; let decl_id = engine_state .find_decl("run-external".as_bytes(), &[]) - .ok_or(ShellError::ExternalNotSupported(head_span))?; + .ok_or(ShellError::ExternalNotSupported { span: head_span })?; let command = engine_state.get_decl(decl_id); @@ -54,11 +54,11 @@ impl Command for KnownExternal { let extern_name = if let Some(name_bytes) = engine_state.find_decl_name(call.decl_id, &[]) { String::from_utf8_lossy(name_bytes) } else { - return Err(ShellError::NushellFailedSpanned( - "known external name not found".to_string(), - "could not find name for this command".to_string(), - call.head, - )); + return Err(ShellError::NushellFailedSpanned { + msg: "known external name not found".to_string(), + label: "could not find name for this command".to_string(), + span: call.head, + }); }; let extern_name: Vec<_> = extern_name.split(' ').collect(); diff --git a/crates/nu-plugin/src/protocol/evaluated_call.rs b/crates/nu-plugin/src/protocol/evaluated_call.rs index a79e4e1447..b7ea8456ca 100644 --- a/crates/nu-plugin/src/protocol/evaluated_call.rs +++ b/crates/nu-plugin/src/protocol/evaluated_call.rs @@ -97,12 +97,12 @@ impl EvaluatedCall { if let Some(value) = self.nth(pos) { FromValue::from_value(&value) } else if self.positional.is_empty() { - Err(ShellError::AccessEmptyContent(self.head)) + Err(ShellError::AccessEmptyContent { span: self.head }) } else { - Err(ShellError::AccessBeyondEnd( - self.positional.len() - 1, - self.head, - )) + Err(ShellError::AccessBeyondEnd { + max_idx: self.positional.len() - 1, + span: self.head, + }) } } } diff --git a/crates/nu-plugin/src/protocol/mod.rs b/crates/nu-plugin/src/protocol/mod.rs index 211865da1f..dcae6411bc 100644 --- a/crates/nu-plugin/src/protocol/mod.rs +++ b/crates/nu-plugin/src/protocol/mod.rs @@ -59,7 +59,12 @@ impl From for LabeledError { ShellError::GenericError(label, msg, span, _help, _related) => { LabeledError { label, msg, span } } - ShellError::CantConvert(expected, input, span, _help) => LabeledError { + ShellError::CantConvert { + to_type: expected, + from_type: input, + span, + help: _help, + } => LabeledError { label: format!("Can't convert to {expected}"), msg: format!("can't convert {expected} to {input}"), span: Some(span), diff --git a/crates/nu-protocol/src/alias.rs b/crates/nu-protocol/src/alias.rs index 041d7ef911..e8c668922a 100644 --- a/crates/nu-protocol/src/alias.rs +++ b/crates/nu-protocol/src/alias.rs @@ -50,11 +50,11 @@ impl Command for Alias { call: &Call, _input: PipelineData, ) -> Result { - Err(ShellError::NushellFailedSpanned( - "Can't run alias directly. Unwrap it first".to_string(), - "originates from here".to_string(), - call.head, - )) + Err(ShellError::NushellFailedSpanned { + msg: "Can't run alias directly. Unwrap it first".to_string(), + label: "originates from here".to_string(), + span: call.head, + }) } fn examples(&self) -> Vec { diff --git a/crates/nu-protocol/src/engine/stack.rs b/crates/nu-protocol/src/engine/stack.rs index 85e6c223aa..11ba821434 100644 --- a/crates/nu-protocol/src/engine/stack.rs +++ b/crates/nu-protocol/src/engine/stack.rs @@ -108,7 +108,7 @@ impl Stack { return Ok(v.clone().with_span(span)); } - Err(ShellError::VariableNotFoundAtRuntime(span)) + Err(ShellError::VariableNotFoundAtRuntime { span }) } pub fn get_var_with_origin(&self, var_id: VarId, span: Span) -> Result { @@ -116,7 +116,7 @@ impl Stack { return Ok(v.clone()); } - Err(ShellError::VariableNotFoundAtRuntime(span)) + Err(ShellError::VariableNotFoundAtRuntime { span }) } pub fn add_var(&mut self, var_id: VarId, value: Value) { @@ -152,7 +152,9 @@ impl Stack { self.active_overlays .last() .cloned() - .ok_or_else(|| ShellError::NushellFailed("No active overlay".into())) + .ok_or_else(|| ShellError::NushellFailed { + msg: "No active overlay".into(), + }) } pub fn captures_to_stack(&self, captures: &HashMap) -> Stack { diff --git a/crates/nu-protocol/src/pipeline_data.rs b/crates/nu-protocol/src/pipeline_data.rs index ac3da856a5..5182cfb41b 100644 --- a/crates/nu-protocol/src/pipeline_data.rs +++ b/crates/nu-protocol/src/pipeline_data.rs @@ -587,12 +587,10 @@ impl PipelineData { let stderr = stderr_handler.map(|(handler, stderr_span, stderr_ctrlc)| { let stderr_bytes = handler .join() - .map_err(|err| { - ShellError::ExternalCommand( - "Fail to receive external commands stderr message".to_string(), - format!("{err:?}"), - stderr_span, - ) + .map_err(|err| ShellError::ExternalCommand { + label: "Fail to receive external commands stderr message".to_string(), + help: format!("{err:?}"), + span: stderr_span, }) .unwrap_or_default(); RawStream::new( diff --git a/crates/nu-protocol/src/shell_error.rs b/crates/nu-protocol/src/shell_error.rs index 01a3ee521f..47846d9f50 100644 --- a/crates/nu-protocol/src/shell_error.rs +++ b/crates/nu-protocol/src/shell_error.rs @@ -226,15 +226,6 @@ pub enum ShellError { span: Span, }, - /// This build of nushell implements this feature, but it has not been enabled. - /// - /// ## Resolution - /// - /// Rebuild nushell with the appropriate feature enabled. - #[error("Feature not enabled.")] - #[diagnostic(code(nu::shell::feature_not_enabled))] - FeatureNotEnabled(#[label = "feature not enabled"] Span), - /// You're trying to run an unsupported external command. /// /// ## Resolution @@ -242,8 +233,12 @@ pub enum ShellError { /// Make sure there's an appropriate `run-external` declaration for this external command. #[error("Running external commands not supported")] #[diagnostic(code(nu::shell::external_commands))] - ExternalNotSupported(#[label = "external not supported"] Span), + ExternalNotSupported { + #[label = "external not supported"] + span: Span, + }, + // TODO: consider moving to a more generic error variant for invalid values /// The given probability input is invalid. The probability must be between 0 and 1. /// /// ## Resolution @@ -251,7 +246,10 @@ pub enum ShellError { /// Make sure the probability is between 0 and 1 and try again. #[error("Invalid Probability.")] #[diagnostic(code(nu::shell::invalid_probability))] - InvalidProbability(#[label = "invalid probability"] Span), + InvalidProbability { + #[label = "invalid probability: must be between 0 and 1"] + span: Span, + }, /// The first value in a `..` range must be compatible with the second one. /// @@ -272,40 +270,47 @@ pub enum ShellError { /// ## Resolution /// /// It is very likely that this is a bug. Please file an issue at https://github.com/nushell/nushell/issues with relevant information. - #[error("Nushell failed: {0}.")] - #[diagnostic(code(nu::shell::nushell_failed))] + #[error("Nushell failed: {msg}.")] + #[diagnostic( + code(nu::shell::nushell_failed), + help( + "This shouldn't happen. Please file an issue: https://github.com/nushell/nushell/issues" + ))] // Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable - NushellFailed(String), + NushellFailed { msg: String }, /// Catastrophic nushell failure. This reflects a completely unexpected or unrecoverable error. /// /// ## Resolution /// /// It is very likely that this is a bug. Please file an issue at https://github.com/nushell/nushell/issues with relevant information. - #[error("Nushell failed: {0}.")] - #[diagnostic(code(nu::shell::nushell_failed_spanned))] + #[error("Nushell failed: {msg}.")] + #[diagnostic( + code(nu::shell::nushell_failed_spanned), + help( + "This shouldn't happen. Please file an issue: https://github.com/nushell/nushell/issues" + ))] // Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable - NushellFailedSpanned(String, String, #[label = "{1}"] Span), + NushellFailedSpanned { + msg: String, + label: String, + #[label = "{label}"] + span: Span, + }, /// Catastrophic nushell failure. This reflects a completely unexpected or unrecoverable error. /// /// ## Resolution /// /// It is very likely that this is a bug. Please file an issue at https://github.com/nushell/nushell/issues with relevant information. - #[error("Nushell failed: {0}.")] + #[error("Nushell failed: {msg}.")] #[diagnostic(code(nu::shell::nushell_failed_help))] // Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable - NushellFailedHelp(String, #[help] String), - - /// Catastrophic nushell failure. This reflects a completely unexpected or unrecoverable error. - /// - /// ## Resolution - /// - /// It is very likely that this is a bug. Please file an issue at https://github.com/nushell/nushell/issues with relevant information. - #[error("Nushell failed: {0}.")] - #[diagnostic(code(nu::shell::nushell_failed_spanned_help))] - // Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable - NushellFailedSpannedHelp(String, String, #[label = "{1}"] Span, #[help] String), + NushellFailedHelp { + msg: String, + #[help] + help: String, + }, /// A referenced variable was not found at runtime. /// @@ -314,43 +319,49 @@ pub enum ShellError { /// Check the variable name. Did you typo it? Did you forget to declare it? Is the casing right? #[error("Variable not found")] #[diagnostic(code(nu::shell::variable_not_found))] - VariableNotFoundAtRuntime(#[label = "variable not found"] Span), + VariableNotFoundAtRuntime { + #[label = "variable not found"] + span: Span, + }, /// A referenced environment variable was not found at runtime. /// /// ## Resolution /// /// Check the environment variable name. Did you typo it? Did you forget to declare it? Is the casing right? - #[error("Environment variable '{0}' not found")] + #[error("Environment variable '{envvar_name}' not found")] #[diagnostic(code(nu::shell::env_variable_not_found))] - EnvVarNotFoundAtRuntime(String, #[label = "environment variable not found"] Span), + EnvVarNotFoundAtRuntime { + envvar_name: String, + #[label = "environment variable not found"] + span: Span, + }, /// A referenced module was not found at runtime. /// /// ## Resolution /// /// Check the module name. Did you typo it? Did you forget to declare it? Is the casing right? - #[error("Module '{0}' not found")] + #[error("Module '{mod_name}' not found")] #[diagnostic(code(nu::shell::module_not_found))] - ModuleNotFoundAtRuntime(String, #[label = "module not found"] Span), - - /// A referenced module or overlay was not found at runtime. - /// - /// ## Resolution - /// - /// Check the module name. Did you typo it? Did you forget to declare it? Is the casing right? - #[error("Module or overlay'{0}' not found")] - #[diagnostic(code(nu::shell::module_or_overlay_not_found))] - ModuleOrOverlayNotFoundAtRuntime(String, #[label = "not a module or overlay"] Span), + ModuleNotFoundAtRuntime { + mod_name: String, + #[label = "module not found"] + span: Span, + }, /// A referenced overlay was not found at runtime. /// /// ## Resolution /// /// Check the overlay name. Did you typo it? Did you forget to declare it? Is the casing right? - #[error("Overlay '{0}' not found")] + #[error("Overlay '{overlay_name}' not found")] #[diagnostic(code(nu::shell::overlay_not_found))] - OverlayNotFoundAtRuntime(String, #[label = "overlay not found"] Span), + OverlayNotFoundAtRuntime { + overlay_name: String, + #[label = "overlay not found"] + span: Span, + }, /// The given item was not found. This is a fairly generic error that depends on context. /// @@ -359,66 +370,82 @@ pub enum ShellError { /// This error is triggered in various places, and simply signals that "something" was not found. Refer to the specific error message for further details. #[error("Not found.")] #[diagnostic(code(nu::parser::not_found))] - NotFound(#[label = "did not find anything under this name"] Span), + NotFound { + #[label = "did not find anything under this name"] + span: Span, + }, /// Failed to convert a value of one type into a different type. /// /// ## Resolution /// /// Not all values can be coerced this way. Check the supported type(s) and try again. - #[error("Can't convert to {0}.")] + #[error("Can't convert to {to_type}.")] #[diagnostic(code(nu::shell::cant_convert))] - CantConvert( - String, - String, - #[label("can't convert {1} to {0}")] Span, - #[help] Option, - ), + CantConvert { + to_type: String, + from_type: String, + #[label("can't convert {from_type} to {to_type}")] + span: Span, + #[help] + help: Option, + }, /// Failed to convert a value of one type into a different type. Includes hint for what the first value is. /// /// ## Resolution /// /// Not all values can be coerced this way. Check the supported type(s) and try again. - #[error("Can't convert {1} `{2}` to {0}.")] + #[error("Can't convert {from_type} `{details}` to {to_type}.")] #[diagnostic(code(nu::shell::cant_convert_with_value))] - CantConvertWithValue( - String, - String, - String, - #[label("can't be converted to {0}")] Span, - #[label("this {1} value...")] Span, - #[help] Option, - ), + CantConvertWithValue { + to_type: String, + from_type: String, + details: String, + #[label("can't be converted to {to_type}")] + dst_span: Span, + #[label("this {from_type} value...")] + src_span: Span, + #[help] + help: Option, + }, /// An environment variable cannot be represented as a string. /// /// ## Resolution /// /// Not all types can be converted to environment variable values, which must be strings. Check the input type and try again. - #[error("{0} is not representable as a string.")] + #[error("'{envvar_name}' is not representable as a string.")] #[diagnostic( - code(nu::shell::env_var_not_a_string), - help( - r#"The '{0}' environment variable must be a string or be convertible to a string. -Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVERSIONS."# - ) - )] - EnvVarNotAString(String, #[label("value not representable as a string")] Span), + code(nu::shell::env_var_not_a_string), + help( + r#"The '{envvar_name}' environment variable must be a string or be convertible to a string. + Either make sure '{envvar_name}' is a string, or add a 'to_string' entry for it in ENV_CONVERSIONS."# + ) + )] + EnvVarNotAString { + envvar_name: String, + #[label("value not representable as a string")] + span: Span, + }, /// This environment variable cannot be set manually. /// /// ## Resolution /// /// This environment variable is set automatically by Nushell and cannot not be set manually. - #[error("{0} cannot be set manually.")] + #[error("{envvar_name} cannot be set manually.")] #[diagnostic( code(nu::shell::automatic_env_var_set_manually), help( - r#"The environment variable '{0}' is set automatically by Nushell and cannot not be set manually."# + r#"The environment variable '{envvar_name}' is set automatically by Nushell and cannot not be set manually."# ) )] - AutomaticEnvVarSetManually(String, #[label("cannot set '{0}' manually")] Span), + AutomaticEnvVarSetManually { + envvar_name: String, + #[label("cannot set '{envvar_name}' manually")] + span: Span, + }, /// It is not possible to replace the entire environment at once /// @@ -429,9 +456,12 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE #[error("Cannot replace environment.")] #[diagnostic( code(nu::shell::cannot_replace_env), - help(r#"Assigning a value to $env is not allowed."#) + help(r#"Assigning a value to '$env' is not allowed."#) )] - CannotReplaceEnv(#[label("setting $env not allowed")] Span), + CannotReplaceEnv { + #[label("setting '$env' not allowed")] + span: Span, + }, /// Division by zero is not a thing. /// @@ -440,7 +470,10 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Add a guard of some sort to check whether a denominator input to this division is zero, and branch off if that's the case. #[error("Division by zero.")] #[diagnostic(code(nu::shell::division_by_zero))] - DivisionByZero(#[label("division by zero")] Span), + DivisionByZero { + #[label("division by zero")] + span: Span, + }, /// An error happened while tryin to create a range. /// @@ -451,28 +484,36 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Check your range values to make sure they're countable and would not loop forever. #[error("Can't convert range to countable values")] #[diagnostic(code(nu::shell::range_to_countable))] - CannotCreateRange(#[label = "can't convert to countable values"] Span), + CannotCreateRange { + #[label = "can't convert to countable values"] + span: Span, + }, /// You attempted to access an index beyond the available length of a value. /// /// ## Resolution /// /// Check your lengths and try again. - #[error("Row number too large (max: {0}).")] + #[error("Row number too large (max: {max_idx}).")] #[diagnostic(code(nu::shell::access_beyond_end))] - AccessBeyondEnd(usize, #[label = "index too large (max: {0})"] Span), + AccessBeyondEnd { + max_idx: usize, + #[label = "index too large (max: {max_idx})"] + span: Span, + }, /// You attempted to insert data at a list position higher than the end. /// /// ## Resolution /// /// To insert data into a list, assign to the last used index + 1. - #[error("Inserted at wrong row number (should be {0}).")] + #[error("Inserted at wrong row number (should be {available_idx}).")] #[diagnostic(code(nu::shell::access_beyond_end))] - InsertAfterNextFreeIndex( - usize, - #[label = "can't insert at index (the next available index is {0})"] Span, - ), + InsertAfterNextFreeIndex { + available_idx: usize, + #[label = "can't insert at index (the next available index is {available_idx})"] + span: Span, + }, /// You attempted to access an index when it's empty. /// @@ -481,8 +522,12 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Check your lengths and try again. #[error("Row number too large (empty content).")] #[diagnostic(code(nu::shell::access_beyond_end))] - AccessEmptyContent(#[label = "index too large (empty content)"] Span), + AccessEmptyContent { + #[label = "index too large (empty content)"] + span: Span, + }, + // TODO: check to be taken over by `AccessBeyondEnd` /// You attempted to access an index beyond the available length of a stream. /// /// ## Resolution @@ -490,7 +535,10 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Check your lengths and try again. #[error("Row number too large.")] #[diagnostic(code(nu::shell::access_beyond_end_of_stream))] - AccessBeyondEndOfStream(#[label = "index too large"] Span), + AccessBeyondEndOfStream { + #[label = "index too large"] + span: Span, + }, /// Tried to index into a type that does not support pathed access. /// @@ -499,7 +547,11 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Check your types. Only composite types can be pathed into. #[error("Data cannot be accessed with a cell path")] #[diagnostic(code(nu::shell::incompatible_path_access))] - IncompatiblePathAccess(String, #[label("{0} doesn't support cell paths")] Span), + IncompatiblePathAccess { + type_name: String, + #[label("{type_name} doesn't support cell paths")] + span: Span, + }, /// The requested column does not exist. /// @@ -508,11 +560,13 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Check the spelling of your column name. Did you forget to rename a column somewhere? #[error("Cannot find column")] #[diagnostic(code(nu::shell::column_not_found))] - CantFindColumn( - String, - #[label = "cannot find column '{0}'"] Span, - #[label = "value originates here"] Span, - ), + CantFindColumn { + col_name: String, + #[label = "cannot find column '{col_name}'"] + span: Span, + #[label = "value originates here"] + src_span: Span, + }, /// Attempted to insert a column into a table, but a column with that name already exists. /// @@ -521,11 +575,13 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Drop or rename the existing column (check `rename -h`) and try again. #[error("Column already exists")] #[diagnostic(code(nu::shell::column_already_exists))] - ColumnAlreadyExists( - String, - #[label = "column '{0}' already exists"] Span, - #[label = "value originates here"] Span, - ), + ColumnAlreadyExists { + col_name: String, + #[label = "column '{col_name}' already exists"] + span: Span, + #[label = "value originates here"] + src_span: Span, + }, /// The given operation can only be performed on lists. /// @@ -534,10 +590,12 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// Check the input type to this command. Are you sure it's a list? #[error("Not a list value")] #[diagnostic(code(nu::shell::not_a_list))] - NotAList( - #[label = "value not a list"] Span, - #[label = "value originates here"] Span, - ), + NotAList { + #[label = "value not a list"] + dst_span: Span, + #[label = "value originates here"] + src_span: Span, + }, /// An error happened while performing an external command. /// @@ -545,8 +603,13 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE /// /// This error is fairly generic. Refer to the specific error message for further details. #[error("External command failed")] - #[diagnostic(code(nu::shell::external_command), help("{1}"))] - ExternalCommand(String, String, #[label("{0}")] Span), + #[diagnostic(code(nu::shell::external_command), help("{help}"))] + ExternalCommand { + label: String, + help: String, + #[label("{label}")] + span: Span, + }, /// An operation was attempted with an input unsupported for some reason. /// diff --git a/crates/nu-protocol/src/value/custom_value.rs b/crates/nu-protocol/src/value/custom_value.rs index 40cf474ad1..531a9c7cf7 100644 --- a/crates/nu-protocol/src/value/custom_value.rs +++ b/crates/nu-protocol/src/value/custom_value.rs @@ -27,17 +27,17 @@ pub trait CustomValue: fmt::Debug + Send + Sync { // Follow cell path functions fn follow_path_int(&self, _count: usize, span: Span) -> Result { - Err(ShellError::IncompatiblePathAccess( - format!("{} doesn't support path access", self.value_string()), + Err(ShellError::IncompatiblePathAccess { + type_name: self.value_string(), span, - )) + }) } fn follow_path_string(&self, _column_name: String, span: Span) -> Result { - Err(ShellError::IncompatiblePathAccess( - format!("{} doesn't support path access", self.value_string()), + Err(ShellError::IncompatiblePathAccess { + type_name: self.value_string(), span, - )) + }) } // ordering with other value diff --git a/crates/nu-protocol/src/value/from.rs b/crates/nu-protocol/src/value/from.rs index fb996c9bc9..a8b994e828 100644 --- a/crates/nu-protocol/src/value/from.rs +++ b/crates/nu-protocol/src/value/from.rs @@ -4,12 +4,12 @@ impl Value { pub fn as_f64(&self) -> Result { match self { Value::Float { val, .. } => Ok(*val), - x => Err(ShellError::CantConvert( - "f64".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "f64".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } @@ -18,12 +18,12 @@ impl Value { Value::Int { val, .. } => Ok(*val), Value::Filesize { val, .. } => Ok(*val), Value::Duration { val, .. } => Ok(*val), - x => Err(ShellError::CantConvert( - "i64".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "i64".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } } diff --git a/crates/nu-protocol/src/value/from_value.rs b/crates/nu-protocol/src/value/from_value.rs index ed437adaf9..33510b666b 100644 --- a/crates/nu-protocol/src/value/from_value.rs +++ b/crates/nu-protocol/src/value/from_value.rs @@ -34,12 +34,12 @@ impl FromValue for Spanned { span: *span, }), - v => Err(ShellError::CantConvert( - "integer".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "integer".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -51,12 +51,12 @@ impl FromValue for i64 { Value::Filesize { val, .. } => Ok(*val), Value::Duration { val, .. } => Ok(*val), - v => Err(ShellError::CantConvert( - "integer".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "integer".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -73,12 +73,12 @@ impl FromValue for Spanned { span: *span, }), - v => Err(ShellError::CantConvert( - "float".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "float".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -88,12 +88,12 @@ impl FromValue for f64 { match v { Value::Float { val, .. } => Ok(*val), Value::Int { val, .. } => Ok(*val as f64), - v => Err(ShellError::CantConvert( - "float".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "float".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -132,12 +132,12 @@ impl FromValue for Spanned { } } - v => Err(ShellError::CantConvert( - "non-negative integer".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "non-negative integer".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -167,12 +167,12 @@ impl FromValue for usize { } } - v => Err(ShellError::CantConvert( - "non-negative integer".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "non-negative integer".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -183,12 +183,12 @@ impl FromValue for String { match v { Value::CellPath { val, .. } => Ok(val.into_string()), Value::String { val, .. } => Ok(val.clone()), - v => Err(ShellError::CantConvert( - "string".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -200,12 +200,12 @@ impl FromValue for Spanned { Value::CellPath { val, .. } => val.into_string(), Value::String { val, .. } => val.clone(), v => { - return Err(ShellError::CantConvert( - "string".into(), - v.get_type().to_string(), - v.span()?, - None, - )) + return Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }) } }, span: v.span()?, @@ -221,20 +221,20 @@ impl FromValue for Vec { .iter() .map(|val| match val { Value::String { val, .. } => Ok(val.clone()), - c => Err(ShellError::CantConvert( - "string".into(), - c.get_type().to_string(), - c.span()?, - None, - )), + c => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: c.get_type().to_string(), + span: c.span()?, + help: None, + }), }) .collect::, ShellError>>(), - v => Err(ShellError::CantConvert( - "string".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -250,20 +250,20 @@ impl FromValue for Vec> { item: val.clone(), span: *span, }), - c => Err(ShellError::CantConvert( - "string".into(), - c.get_type().to_string(), - c.span()?, - None, - )), + c => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: c.get_type().to_string(), + span: c.span()?, + help: None, + }), }) .collect::>, ShellError>>(), - v => Err(ShellError::CantConvert( - "string".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -275,20 +275,20 @@ impl FromValue for Vec { .iter() .map(|val| match val { Value::Bool { val, .. } => Ok(*val), - c => Err(ShellError::CantConvert( - "bool".into(), - c.get_type().to_string(), - c.span()?, - None, - )), + c => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: c.get_type().to_string(), + span: c.span()?, + help: None, + }), }) .collect::, ShellError>>(), - v => Err(ShellError::CantConvert( - "bool".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -316,12 +316,12 @@ impl FromValue for CellPath { }) } } - x => Err(ShellError::CantConvert( - "cell path".into(), - x.get_type().to_string(), + x => Err(ShellError::CantConvert { + to_type: "cell path".into(), + from_type: x.get_type().to_string(), span, - None, - )), + help: None, + }), } } } @@ -330,12 +330,12 @@ impl FromValue for bool { fn from_value(v: &Value) -> Result { match v { Value::Bool { val, .. } => Ok(*val), - v => Err(ShellError::CantConvert( - "bool".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -347,12 +347,12 @@ impl FromValue for Spanned { item: *val, span: *span, }), - v => Err(ShellError::CantConvert( - "bool".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -361,12 +361,12 @@ impl FromValue for DateTime { fn from_value(v: &Value) -> Result { match v { Value::Date { val, .. } => Ok(*val), - v => Err(ShellError::CantConvert( - "date".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "date".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -378,12 +378,12 @@ impl FromValue for Spanned> { item: *val, span: *span, }), - v => Err(ShellError::CantConvert( - "date".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "date".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -392,12 +392,12 @@ impl FromValue for Range { fn from_value(v: &Value) -> Result { match v { Value::Range { val, .. } => Ok((**val).clone()), - v => Err(ShellError::CantConvert( - "range".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "range".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -409,12 +409,12 @@ impl FromValue for Spanned { item: (**val).clone(), span: *span, }), - v => Err(ShellError::CantConvert( - "range".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "range".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -424,12 +424,12 @@ impl FromValue for Vec { match v { Value::Binary { val, .. } => Ok(val.clone()), Value::String { val, .. } => Ok(val.bytes().collect()), - v => Err(ShellError::CantConvert( - "binary data".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "binary data".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -445,12 +445,12 @@ impl FromValue for Spanned> { item: val.bytes().collect(), span: *span, }), - v => Err(ShellError::CantConvert( - "binary data".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "binary data".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -463,12 +463,12 @@ impl FromValue for Spanned { .map_err(|err| ShellError::FileNotFoundCustom(err.to_string(), *span))?, span: *span, }), - v => Err(ShellError::CantConvert( - "range".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "range".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -478,12 +478,12 @@ impl FromValue for Vec { // FIXME: we may want to fail a little nicer here match v { Value::List { vals, .. } => Ok(vals.clone()), - v => Err(ShellError::CantConvert( - "Vector of values".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "Vector of values".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -493,12 +493,12 @@ impl FromValue for (Vec, Vec) { fn from_value(v: &Value) -> Result { match v { Value::Record { cols, vals, .. } => Ok((cols.clone(), vals.clone())), - v => Err(ShellError::CantConvert( - "Record".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "Record".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -514,12 +514,12 @@ impl FromValue for Closure { block_id: *val, captures: HashMap::new(), }), - v => Err(ShellError::CantConvert( - "Closure".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "Closure".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -528,12 +528,12 @@ impl FromValue for Block { fn from_value(v: &Value) -> Result { match v { Value::Block { val, .. } => Ok(Block { block_id: *val }), - v => Err(ShellError::CantConvert( - "Block".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "Block".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } @@ -552,12 +552,12 @@ impl FromValue for Spanned { }, span: *span, }), - v => Err(ShellError::CantConvert( - "Closure".into(), - v.get_type().to_string(), - v.span()?, - None, - )), + v => Err(ShellError::CantConvert { + to_type: "Closure".into(), + from_type: v.get_type().to_string(), + span: v.span()?, + help: None, + }), } } } diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index cdfbee834f..507c07d235 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -197,21 +197,21 @@ impl Value { Value::Binary { val, .. } => Ok(match std::str::from_utf8(val) { Ok(s) => s.to_string(), Err(_) => { - return Err(ShellError::CantConvert( - "string".into(), - "binary".into(), - self.span()?, - None, - )); + return Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: "binary".into(), + span: self.span()?, + help: None, + }); } }), Value::Date { val, .. } => Ok(val.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)), - x => Err(ShellError::CantConvert( - "string".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } @@ -227,32 +227,32 @@ impl Value { span: *span, }, Err(_) => { - return Err(ShellError::CantConvert( - "string".into(), - "binary".into(), - self.span()?, - None, - )) + return Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: "binary".into(), + span: self.span()?, + help: None, + }) } }), - x => Err(ShellError::CantConvert( - "string".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } pub fn as_path(&self) -> Result { match self { Value::String { val, .. } => Ok(PathBuf::from(val)), - x => Err(ShellError::CantConvert( - "path".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "path".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } @@ -260,12 +260,12 @@ impl Value { match self { Value::Block { val, .. } => Ok(*val), Value::Closure { val, .. } => Ok(*val), - x => Err(ShellError::CantConvert( - "block".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "block".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } @@ -273,48 +273,48 @@ impl Value { match self { Value::Binary { val, .. } => Ok(val), Value::String { val, .. } => Ok(val.as_bytes()), - x => Err(ShellError::CantConvert( - "binary".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "binary".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } pub fn as_record(&self) -> Result<(&[String], &[Value]), ShellError> { match self { Value::Record { cols, vals, .. } => Ok((cols, vals)), - x => Err(ShellError::CantConvert( - "record".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "record".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } pub fn as_list(&self) -> Result<&[Value], ShellError> { match self { Value::List { vals, .. } => Ok(vals), - x => Err(ShellError::CantConvert( - "list".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "list".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } pub fn as_bool(&self) -> Result { match self { Value::Bool { val, .. } => Ok(*val), - x => Err(ShellError::CantConvert( - "boolean".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "boolean".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } @@ -322,24 +322,24 @@ impl Value { match self { Value::Float { val, .. } => Ok(*val), Value::Int { val, .. } => Ok(*val as f64), - x => Err(ShellError::CantConvert( - "float".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "float".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } pub fn as_integer(&self) -> Result { match self { Value::Int { val, .. } => Ok(*val), - x => Err(ShellError::CantConvert( - "integer".into(), - x.get_type().to_string(), - self.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "integer".into(), + from_type: x.get_type().to_string(), + span: self.span()?, + help: None, + }), } } @@ -722,12 +722,15 @@ impl Value { current = item.clone(); } else if val.is_empty() { err_or_null!( - ShellError::AccessEmptyContent(*origin_span), + ShellError::AccessEmptyContent { span: *origin_span }, *origin_span ) } else { err_or_null!( - ShellError::AccessBeyondEnd(val.len() - 1, *origin_span), + ShellError::AccessBeyondEnd { + max_idx: val.len() - 1, + span: *origin_span + }, *origin_span ); } @@ -737,12 +740,15 @@ impl Value { current = Value::int(*item as i64, *origin_span); } else if val.is_empty() { err_or_null!( - ShellError::AccessEmptyContent(*origin_span), + ShellError::AccessEmptyContent { span: *origin_span }, *origin_span ) } else { err_or_null!( - ShellError::AccessBeyondEnd(val.len() - 1, *origin_span), + ShellError::AccessBeyondEnd { + max_idx: val.len() - 1, + span: *origin_span + }, *origin_span ); } @@ -752,7 +758,7 @@ impl Value { current = item.clone(); } else { err_or_null!( - ShellError::AccessBeyondEndOfStream(*origin_span), + ShellError::AccessBeyondEndOfStream { span: *origin_span }, *origin_span ); } @@ -770,10 +776,10 @@ impl Value { Value::Error { error } => return Err(error.to_owned()), x => { err_or_null!( - ShellError::IncompatiblePathAccess( - format!("{}", x.get_type()), - *origin_span, - ), + ShellError::IncompatiblePathAccess { + type_name: format!("{}", x.get_type()), + span: *origin_span + }, *origin_span ) } @@ -806,11 +812,11 @@ impl Value { } } err_or_null!( - ShellError::CantFindColumn( - column_name.to_string(), - *origin_span, - span, - ), + ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: span + }, *origin_span ); } @@ -830,11 +836,11 @@ impl Value { } } err_or_null!( - ShellError::CantFindColumn( - column_name.to_string(), - *origin_span, - *span, - ), + ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: *span + }, *origin_span ); } @@ -874,13 +880,11 @@ impl Value { Value::nothing(*origin_span) } else { Value::Error { - error: ShellError::CantFindColumn( - column_name.to_string(), - *origin_span, - // Get the exact span of the value, falling back to - // the list's span if it's a Value::Empty - val.span().unwrap_or(*span), - ), + error: ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: val.span().unwrap_or(*span), + }, } }); } @@ -890,13 +894,11 @@ impl Value { Value::nothing(*origin_span) } else { Value::Error { - error: ShellError::CantFindColumn( - column_name.to_string(), - *origin_span, - // Get the exact span of the value, falling back to - // the list's span if it's a Value::Empty - val.span().unwrap_or(*span), - ), + error: ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: val.span().unwrap_or(*span), + }, } }); } @@ -908,11 +910,11 @@ impl Value { }; } else { err_or_null!( - ShellError::CantFindColumn( - column_name.to_string(), - *origin_span, - *span, - ), + ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: *span + }, *origin_span ); } @@ -923,10 +925,10 @@ impl Value { Value::Error { error } => err_or_null!(error.to_owned(), *origin_span), x => { err_or_null!( - ShellError::IncompatiblePathAccess( - format!("{}", x.get_type()), - *origin_span, - ), + ShellError::IncompatiblePathAccess { + type_name: format!("{}", x.get_type()), + span: *origin_span + }, *origin_span ) } @@ -1005,11 +1007,11 @@ impl Value { } Value::Error { error } => return Err(error.to_owned()), v => { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )) + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }) } } } @@ -1042,11 +1044,11 @@ impl Value { } Value::Error { error } => return Err(error.to_owned()), v => { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )) + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }) } }, PathMember::Int { val: row_num, span } => match self { @@ -1058,11 +1060,19 @@ impl Value { // Otherwise, it's prohibited. vals.push(new_val); } else { - return Err(ShellError::InsertAfterNextFreeIndex(vals.len(), *span)); + return Err(ShellError::InsertAfterNextFreeIndex { + available_idx: vals.len(), + span: *span, + }); } } Value::Error { error } => return Err(error.to_owned()), - v => return Err(ShellError::NotAList(*span, v.span()?)), + v => { + return Err(ShellError::NotAList { + dst_span: *span, + src_span: v.span()?, + }) + } }, }, None => { @@ -1118,20 +1128,20 @@ impl Value { } } if !found { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } } Value::Error { error } => return Err(error.to_owned()), v => { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )) + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }) } } } @@ -1152,20 +1162,20 @@ impl Value { } } if !found { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } } Value::Error { error } => return Err(error.to_owned()), v => { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )) + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }) } }, PathMember::Int { val: row_num, span } => match self { @@ -1173,13 +1183,21 @@ impl Value { if let Some(v) = vals.get_mut(*row_num) { v.update_data_at_cell_path(&cell_path[1..], new_val)? } else if vals.is_empty() { - return Err(ShellError::AccessEmptyContent(*span)); + return Err(ShellError::AccessEmptyContent { span: *span }); } else { - return Err(ShellError::AccessBeyondEnd(vals.len() - 1, *span)); + return Err(ShellError::AccessBeyondEnd { + max_idx: vals.len() - 1, + span: *span, + }); } } Value::Error { error } => return Err(error.to_owned()), - v => return Err(ShellError::NotAList(*span, v.span()?)), + v => { + return Err(ShellError::NotAList { + dst_span: *span, + src_span: v.span()?, + }) + } }, }, None => { @@ -1216,19 +1234,19 @@ impl Value { } } if !found { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } } v => { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )) + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }) } } } @@ -1248,19 +1266,19 @@ impl Value { } } if !found { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } Ok(()) } - v => Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )), + v => Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }), }, PathMember::Int { val: row_num, span } => match self { Value::List { vals, .. } => { @@ -1268,12 +1286,18 @@ impl Value { vals.remove(*row_num); Ok(()) } else if vals.is_empty() { - Err(ShellError::AccessEmptyContent(*span)) + Err(ShellError::AccessEmptyContent { span: *span }) } else { - Err(ShellError::AccessBeyondEnd(vals.len() - 1, *span)) + Err(ShellError::AccessBeyondEnd { + max_idx: vals.len() - 1, + span: *span, + }) } } - v => Err(ShellError::NotAList(*span, v.span()?)), + v => Err(ShellError::NotAList { + dst_span: *span, + src_span: v.span()?, + }), }, } } @@ -1300,19 +1324,19 @@ impl Value { } } if !found { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } } v => { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )) + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }) } } } @@ -1333,31 +1357,37 @@ impl Value { } } if !found { - return Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } Ok(()) } - v => Err(ShellError::CantFindColumn( - col_name.to_string(), - *span, - v.span()?, - )), + v => Err(ShellError::CantFindColumn { + col_name: col_name.to_string(), + span: *span, + src_span: v.span()?, + }), }, PathMember::Int { val: row_num, span } => match self { Value::List { vals, .. } => { if let Some(v) = vals.get_mut(*row_num) { v.remove_data_at_cell_path(&cell_path[1..]) } else if vals.is_empty() { - Err(ShellError::AccessEmptyContent(*span)) + Err(ShellError::AccessEmptyContent { span: *span }) } else { - Err(ShellError::AccessBeyondEnd(vals.len() - 1, *span)) + Err(ShellError::AccessBeyondEnd { + max_idx: vals.len() - 1, + span: *span, + }) } } - v => Err(ShellError::NotAList(*span, v.span()?)), + v => Err(ShellError::NotAList { + dst_span: *span, + src_span: v.span()?, + }), }, } } @@ -1387,11 +1417,11 @@ impl Value { for col in cols.iter().zip(vals.iter_mut()) { if col.0 == col_name { if cell_path.len() == 1 { - return Err(ShellError::ColumnAlreadyExists( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::ColumnAlreadyExists { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } else { return col.1.insert_data_at_cell_path( &cell_path[1..], @@ -1426,11 +1456,11 @@ impl Value { for col in cols.iter().zip(vals.iter_mut()) { if col.0 == col_name { if cell_path.len() == 1 { - return Err(ShellError::ColumnAlreadyExists( - col_name.to_string(), - *span, - *v_span, - )); + return Err(ShellError::ColumnAlreadyExists { + col_name: col_name.to_string(), + span: *span, + src_span: *v_span, + }); } else { return col.1.insert_data_at_cell_path( &cell_path[1..], @@ -1462,10 +1492,18 @@ impl Value { // Otherwise, it's prohibited. vals.push(new_val); } else { - return Err(ShellError::InsertAfterNextFreeIndex(vals.len(), *span)); + return Err(ShellError::InsertAfterNextFreeIndex { + available_idx: vals.len(), + span: *span, + }); } } - v => return Err(ShellError::NotAList(*span, v.span()?)), + v => { + return Err(ShellError::NotAList { + dst_span: *span, + src_span: v.span()?, + }) + } }, }, None => { @@ -2307,7 +2345,7 @@ impl Value { }) } } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2317,7 +2355,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -2327,7 +2365,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2337,7 +2375,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { @@ -2354,7 +2392,7 @@ impl Value { }) } } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -2364,7 +2402,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2374,7 +2412,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { @@ -2391,7 +2429,7 @@ impl Value { }) } } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -2401,7 +2439,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2411,7 +2449,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::CustomValue { val: lhs, span }, rhs) => { @@ -2439,7 +2477,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2451,7 +2489,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -2463,7 +2501,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2475,7 +2513,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { @@ -2487,7 +2525,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -2499,7 +2537,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2511,7 +2549,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { @@ -2523,7 +2561,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -2535,7 +2573,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -2547,7 +2585,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::CustomValue { val: lhs, span }, rhs) => { @@ -3082,7 +3120,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -3092,7 +3130,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { @@ -3102,7 +3140,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { @@ -3112,7 +3150,7 @@ impl Value { span, }) } else { - Err(ShellError::DivisionByZero(op)) + Err(ShellError::DivisionByZero { span: op }) } } (Value::CustomValue { val: lhs, span }, rhs) => { diff --git a/crates/nu-protocol/src/value/range.rs b/crates/nu-protocol/src/value/range.rs index 3d1174b9d2..3998059b4b 100644 --- a/crates/nu-protocol/src/value/range.rs +++ b/crates/nu-protocol/src/value/range.rs @@ -68,7 +68,7 @@ impl Range { incr.eq(expr_span, &zero, expr_span), Ok(Value::Bool { val: true, .. }) ) { - return Err(ShellError::CannotCreateRange(expr_span)); + return Err(ShellError::CannotCreateRange { span: expr_span }); } // If to > from, then incr > 0, otherwise we iterate forever @@ -76,7 +76,7 @@ impl Range { to.gt(operator.span, &from, expr_span)?, incr.gt(operator.next_op_span, &zero, expr_span)?, ) { - return Err(ShellError::CannotCreateRange(expr_span)); + return Err(ShellError::CannotCreateRange { span: expr_span }); } // If to < from, then incr < 0, otherwise we iterate forever @@ -84,7 +84,7 @@ impl Range { to.lt(operator.span, &from, expr_span)?, incr.lt(operator.next_op_span, &zero, expr_span)?, ) { - return Err(ShellError::CannotCreateRange(expr_span)); + return Err(ShellError::CannotCreateRange { span: expr_span }); } Ok(Range { @@ -218,7 +218,7 @@ impl Iterator for RangeIterator { } else { self.done = true; return Some(Value::Error { - error: ShellError::CannotCreateRange(self.span), + error: ShellError::CannotCreateRange { span: self.span }, }); }; diff --git a/crates/nu_plugin_custom_values/src/cool_custom_value.rs b/crates/nu_plugin_custom_values/src/cool_custom_value.rs index 4e81da8f07..900b693388 100644 --- a/crates/nu_plugin_custom_values/src/cool_custom_value.rs +++ b/crates/nu_plugin_custom_values/src/cool_custom_value.rs @@ -26,20 +26,20 @@ impl CoolCustomValue { if let Some(cool) = val.as_any().downcast_ref::() { Ok(cool.clone()) } else { - Err(ShellError::CantConvert( - "cool".into(), - "non-cool".into(), - *span, - None, - )) + Err(ShellError::CantConvert { + to_type: "cool".into(), + from_type: "non-cool".into(), + span: *span, + help: None, + }) } } - x => Err(ShellError::CantConvert( - "cool".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "cool".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } } diff --git a/crates/nu_plugin_custom_values/src/main.rs b/crates/nu_plugin_custom_values/src/main.rs index 0c9c152c5d..c36797face 100644 --- a/crates/nu_plugin_custom_values/src/main.rs +++ b/crates/nu_plugin_custom_values/src/main.rs @@ -63,12 +63,12 @@ impl CustomValuePlugin { return Ok(value.into_value(call.head)); } - Err(ShellError::CantConvert( - "cool or second".into(), - "non-cool and non-second".into(), - call.head, - None, - ) + Err(ShellError::CantConvert { + to_type: "cool or second".into(), + from_type: "non-cool and non-second".into(), + span: call.head, + help: None, + } .into()) } } diff --git a/crates/nu_plugin_custom_values/src/second_custom_value.rs b/crates/nu_plugin_custom_values/src/second_custom_value.rs index 17e5b3c26b..617e78f3ab 100644 --- a/crates/nu_plugin_custom_values/src/second_custom_value.rs +++ b/crates/nu_plugin_custom_values/src/second_custom_value.rs @@ -24,19 +24,19 @@ impl SecondCustomValue { match value { Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { Some(value) => Ok(value.clone()), - None => Err(ShellError::CantConvert( - "cool".into(), - "non-cool".into(), - *span, - None, - )), + None => Err(ShellError::CantConvert { + to_type: "cool".into(), + from_type: "non-cool".into(), + span: *span, + help: None, + }), }, - x => Err(ShellError::CantConvert( - "cool".into(), - x.get_type().to_string(), - x.span()?, - None, - )), + x => Err(ShellError::CantConvert { + to_type: "cool".into(), + from_type: x.get_type().to_string(), + span: x.span()?, + help: None, + }), } } } diff --git a/crates/nu_plugin_formats/src/from/eml.rs b/crates/nu_plugin_formats/src/from/eml.rs index c38ed808ac..30b6a9d6b1 100644 --- a/crates/nu_plugin_formats/src/from/eml.rs +++ b/crates/nu_plugin_formats/src/from/eml.rs @@ -145,8 +145,11 @@ fn from_eml(input: &Value, body_preview: usize, head: Span) -> Result