Convert ShellError::UnsupportedInput to named fields (#10971)

# Description

This is easy to do with rust-analyzer, but I didn't want to just pump
these all out without feedback.

Part of #10700

# User-Facing Changes

None

# Tests + Formatting

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting

N/A

---------

Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
Eric Hodel 2023-11-07 14:25:32 -08:00 committed by GitHub
parent 45b02ce2ab
commit 7a3cbf43e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 506 additions and 567 deletions

View File

@ -124,12 +124,12 @@ impl Command for ExprDatePart {
"microsecond" => expr_dt.microsecond(), "microsecond" => expr_dt.microsecond(),
"nanosecond" => expr_dt.nanosecond(), "nanosecond" => expr_dt.nanosecond(),
_ => { _ => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
format!("{} is not a valid datepart, expected one of year, month, day, hour, minute, second, millisecond, microsecond, nanosecond", part.item), msg: format!("{} is not a valid datepart, expected one of year, month, day, hour, minute, second, millisecond, microsecond, nanosecond", part.item),
"value originates from here".to_string(), input: "value originates from here".to_string(),
call.head, msg_span: call.head,
part.span, input_span: part.span,
)); });
} }
}.into(); }.into();

View File

@ -98,12 +98,12 @@ fn command(
let value = NuDataFrame::dataframe_into_value(res, call.head); let value = NuDataFrame::dataframe_into_value(res, call.head);
Ok(PipelineData::Value(value, None)) Ok(PipelineData::Value(value, None))
} }
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"Expected the dataframe to have a column".to_string(), msg: "Expected the dataframe to have a column".to_string(),
"".to_string(), input: "".to_string(),
call.head, msg_span: call.head,
call.head, input_span: call.head,
)), }),
} }
} }

View File

@ -855,13 +855,13 @@ fn series_to_values(
Some(val) => val, Some(val) => val,
None => { None => {
return Value::error( return Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"The given local datetime representation is invalid." msg: "The given local datetime representation is invalid."
.to_string(), .to_string(),
format!("timestamp is {a:?}"), input: format!("timestamp is {a:?}"),
span, msg_span: span,
Span::unknown(), input_span: Span::unknown(),
), },
span, span,
) )
} }
@ -871,13 +871,13 @@ fn series_to_values(
Some(val) => val, Some(val) => val,
None => { None => {
return Value::error( return Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"The given local datetime representation is invalid." msg: "The given local datetime representation is invalid."
.to_string(), .to_string(),
format!("timestamp is {a:?}"), input: format!("timestamp is {a:?}"),
span, msg_span: span,
Span::unknown(), input_span: Span::unknown(),
), },
span, span,
) )
} }
@ -923,13 +923,13 @@ fn series_to_values(
Some(val) => val, Some(val) => val,
None => { None => {
return Value::error( return Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"The given local datetime representation is invalid." msg: "The given local datetime representation is invalid."
.to_string(), .to_string(),
format!("timestamp is {a:?}"), input: format!("timestamp is {a:?}"),
span, msg_span: span,
Span::unknown(), input_span: Span::unknown(),
), },
span, span,
) )
} }
@ -939,13 +939,13 @@ fn series_to_values(
Some(val) => val, Some(val) => val,
None => { None => {
return Value::error( return Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"The given local datetime representation is invalid." msg: "The given local datetime representation is invalid."
.to_string(), .to_string(),
format!("timestamp is {a:?}"), input: format!("timestamp is {a:?}"),
span, msg_span: span,
Span::unknown(), input_span: Span::unknown(),
), },
span, span,
) )
} }

View File

@ -427,11 +427,11 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Result<Value, ShellError> {
} }
// the parameter polars_plan::dsl::selector::Selector is not publicly exposed. // the parameter polars_plan::dsl::selector::Selector is not publicly exposed.
// I am not sure what we can meaningfully do with this at this time. // I am not sure what we can meaningfully do with this at this time.
Expr::Selector(_) => Err(ShellError::UnsupportedInput( Expr::Selector(_) => Err(ShellError::UnsupportedInput {
"Expressions of type Selector to Nu Values is not yet supported".to_string(), msg: "Expressions of type Selector to Nu Values is not yet supported".to_string(),
format!("Expression is {expr:?}"), input: format!("Expression is {expr:?}"),
span, msg_span: span,
Span::unknown(), input_span: Span::unknown(),
)), }),
} }
} }

View File

@ -60,12 +60,12 @@ impl Command for BitsNot {
let bytes_len = get_number_bytes(number_bytes.as_ref()); let bytes_len = get_number_bytes(number_bytes.as_ref());
if let NumberBytes::Invalid = bytes_len { if let NumberBytes::Invalid = bytes_len {
if let Some(val) = number_bytes { if let Some(val) = number_bytes {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(), msg: "Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(),
"value originates from here".to_string(), input: "value originates from here".to_string(),
head, msg_span: head,
val.span, input_span: val.span,
)); });
} }
} }

View File

@ -63,12 +63,12 @@ impl Command for BitsRol {
let bytes_len = get_number_bytes(number_bytes.as_ref()); let bytes_len = get_number_bytes(number_bytes.as_ref());
if let NumberBytes::Invalid = bytes_len { if let NumberBytes::Invalid = bytes_len {
if let Some(val) = number_bytes { if let Some(val) = number_bytes {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(), msg: "Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(),
"value originates from here".to_string(), input: "value originates from here".to_string(),
head, msg_span: head,
val.span, input_span: val.span,
)); });
} }
} }
// This doesn't match explicit nulls // This doesn't match explicit nulls

View File

@ -63,12 +63,12 @@ impl Command for BitsRor {
let bytes_len = get_number_bytes(number_bytes.as_ref()); let bytes_len = get_number_bytes(number_bytes.as_ref());
if let NumberBytes::Invalid = bytes_len { if let NumberBytes::Invalid = bytes_len {
if let Some(val) = number_bytes { if let Some(val) = number_bytes {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(), msg: "Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(),
"value originates from here".to_string(), input: "value originates from here".to_string(),
head, msg_span: head,
val.span, input_span: val.span,
)); });
} }
} }
// This doesn't match explicit nulls // This doesn't match explicit nulls

View File

@ -63,12 +63,12 @@ impl Command for BitsShl {
let bytes_len = get_number_bytes(number_bytes.as_ref()); let bytes_len = get_number_bytes(number_bytes.as_ref());
if let NumberBytes::Invalid = bytes_len { if let NumberBytes::Invalid = bytes_len {
if let Some(val) = number_bytes { if let Some(val) = number_bytes {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(), msg: "Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(),
"value originates from here".to_string(), input: "value originates from here".to_string(),
head, msg_span: head,
val.span, input_span: val.span,
)); });
} }
} }
// This doesn't match explicit nulls // This doesn't match explicit nulls

View File

@ -63,12 +63,12 @@ impl Command for BitsShr {
let bytes_len = get_number_bytes(number_bytes.as_ref()); let bytes_len = get_number_bytes(number_bytes.as_ref());
if let NumberBytes::Invalid = bytes_len { if let NumberBytes::Invalid = bytes_len {
if let Some(val) = number_bytes { if let Some(val) = number_bytes {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(), msg: "Only 1, 2, 4, 8, or 'auto' bytes are supported as word sizes".to_string(),
"value originates from here".to_string(), input: "value originates from here".to_string(),
head, msg_span: head,
val.span, input_span: val.span,
)); });
} }
} }
// This doesn't match explicit nulls // This doesn't match explicit nulls

View File

@ -200,13 +200,12 @@ pub fn rotate(
} }
} }
} else { } else {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"list input is empty".to_string(), msg: "list input is empty".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
call.head, msg_span: call.head,
// TODO: Maybe make all Pipelines have spans, so that this doesn't need to be unwrapped. input_span: span.unwrap_or(call.head),
span.unwrap_or(call.head), });
));
} }
let total_columns = &old_column_names.len(); let total_columns = &old_column_names.len();

View File

@ -61,12 +61,12 @@ fn from_url(input: PipelineData, head: Span) -> Result<PipelineData, ShellError>
Ok(PipelineData::Value(Value::record(record, head), metadata)) Ok(PipelineData::Value(Value::record(record, head), metadata))
} }
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"String not compatible with URL encoding".to_string(), msg: "String not compatible with URL encoding".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
)), }),
} }
} }

View File

@ -84,12 +84,13 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
Value::float(val, span) Value::float(val, span)
} else { } else {
Value::error( Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"'arccos' undefined for values outside the closed interval [-1, 1].".into(), msg: "'arccos' undefined for values outside the closed interval [-1, 1]."
"value originates from here".into(), .into(),
head, input: "value originates from here".into(),
span, msg_span: head,
), input_span: span,
},
span, span,
) )
} }

View File

@ -74,12 +74,12 @@ fn operate(value: Value, head: Span) -> Value {
Value::float(val, span) Value::float(val, span)
} else { } else {
Value::error( Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"'arccosh' undefined for values below 1.".into(), msg: "'arccosh' undefined for values below 1.".into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
), },
span, span,
) )
} }

View File

@ -85,12 +85,13 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
Value::float(val, span) Value::float(val, span)
} else { } else {
Value::error( Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"'arcsin' undefined for values outside the closed interval [-1, 1].".into(), msg: "'arcsin' undefined for values outside the closed interval [-1, 1]."
"value originates from here".into(), .into(),
head, input: "value originates from here".into(),
span, msg_span: head,
), input_span: span,
},
span, span,
) )
} }

View File

@ -74,12 +74,13 @@ fn operate(value: Value, head: Span) -> Value {
Value::float(val, span) Value::float(val, span)
} else { } else {
Value::error( Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"'arctanh' undefined for values outside the open interval (-1, 1).".into(), msg: "'arctanh' undefined for values outside the open interval (-1, 1)."
"value originates from here".into(), .into(),
head, input: "value originates from here".into(),
span, msg_span: head,
), input_span: span,
},
head, head,
) )
} }

View File

@ -74,12 +74,12 @@ fn operate(value: Value, head: Span) -> Value {
Value::float(val, span) Value::float(val, span)
} else { } else {
Value::error( Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"'ln' undefined for values outside the open interval (0, Inf).".into(), msg: "'ln' undefined for values outside the open interval (0, Inf).".into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
), },
span, span,
) )
} }

View File

@ -108,26 +108,14 @@ fn action(
Value::Binary { val, .. } => match hex_config.action_type { Value::Binary { val, .. } => match hex_config.action_type {
ActionType::Encode => Value::string(hex_encode(val.as_ref()), command_span), ActionType::Encode => Value::string(hex_encode(val.as_ref()), command_span),
ActionType::Decode => Value::error( ActionType::Decode => Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput { msg: "Binary data can only be encoded".to_string(), input: "value originates from here".into(), msg_span: command_span, input_span: input.span() },
"Binary data can only be encoded".to_string(),
"value originates from here".into(),
command_span,
// This line requires the Value::Error {} match above.
input.span(),
),
command_span, command_span,
), ),
}, },
Value::String { val, .. } => { Value::String { val, .. } => {
match hex_config.action_type { match hex_config.action_type {
ActionType::Encode => Value::error( ActionType::Encode => Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput { msg: "String value can only be decoded".to_string(), input: "value originates from here".into(), msg_span: command_span, input_span: input.span() },
"String value can only be decoded".to_string(),
"value originates from here".into(),
command_span,
// This line requires the Value::Error {} match above.
input.span(),
),
command_span, command_span,
), ),

View File

@ -176,13 +176,12 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value {
Value::Error { .. } => input.clone(), Value::Error { .. } => input.clone(),
other => Value::error( other => Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"Only binary values are supported".into(), msg: "Only binary values are supported".into(),
format!("input type: {:?}", other.get_type()), input: format!("input type: {:?}", other.get_type()),
head, msg_span: head,
// This line requires the Value::Error match above. input_span: other.span(),
other.span(), },
),
head, head,
), ),
} }

View File

@ -102,12 +102,12 @@ impl HashableValue {
// Explicitly propagate errors instead of dropping them. // Explicitly propagate errors instead of dropping them.
Value::Error { error, .. } => Err(*error), Value::Error { error, .. } => Err(*error),
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"input value is not hashable".into(), msg: "input value is not hashable".into(),
format!("input type: {:?}", value.get_type()), input: format!("input type: {:?}", value.get_type()),
span, msg_span: span,
value.span(), input_span: value.span(),
)), }),
} }
} }

View File

@ -162,14 +162,9 @@ fn run_histogram(
let t = v.get_type(); let t = v.get_type();
let span = v.span(); let span = v.span();
inputs.push(HashableValue::from_value(v, head_span).map_err(|_| { inputs.push(HashableValue::from_value(v, head_span).map_err(|_| {
ShellError::UnsupportedInput( ShellError::UnsupportedInput { msg: "Since --column-name was not provided, only lists of hashable values are supported.".to_string(), input: format!(
"Since --column-name was not provided, only lists of hashable values are supported.".to_string(),
format!(
"input type: {t:?}" "input type: {t:?}"
), ), msg_span: head_span, input_span: span }
head_span,
span,
)
})?) })?)
} }
} }

View File

@ -81,12 +81,12 @@ impl Command for LoadEnv {
} }
Ok(PipelineData::empty()) Ok(PipelineData::empty())
} }
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"'load-env' expects a single record".into(), msg: "'load-env' expects a single record".into(),
"value originated from here".into(), input: "value originated from here".into(),
span, msg_span: span,
input.span().unwrap_or(span), input_span: input.span().unwrap_or(span),
)), }),
}, },
} }
} }

View File

@ -469,13 +469,12 @@ fn find_with_rest_and_highlight(
// Propagate errors by explicitly matching them before the final case. // Propagate errors by explicitly matching them before the final case.
Value::Error { error, .. } => return Err(*error), Value::Error { error, .. } => return Err(*error),
other => { other => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"unsupported type from raw stream".into(), msg: "unsupported type from raw stream".into(),
format!("input: {:?}", other.get_type()), input: format!("input: {:?}", other.get_type()),
span, msg_span: span,
// This line requires the Value::Error match above. input_span: other.span(),
other.span(), });
));
} }
} }
} }

View File

@ -208,12 +208,7 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) ->
} }
Value::List { vals, .. } if all && vals.iter().all(|f| f.as_record().is_ok()) => { Value::List { vals, .. } if all && vals.iter().all(|f| f.as_record().is_ok()) => {
if need_flatten && inner_table.is_some() { if need_flatten && inner_table.is_some() {
return vec![Value::error( ShellError::UnsupportedInput( return vec![Value::error( ShellError::UnsupportedInput { msg: "can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(), input: "value originates from here".into(), msg_span: s, input_span: span }, span)
"can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(),
"value originates from here".into(),
s,
span
), span)
]; ];
} }
// it's a table (a list of record, we can flatten inner record) // it's a table (a list of record, we can flatten inner record)
@ -244,12 +239,7 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) ->
} }
Value::List { vals: values, .. } => { Value::List { vals: values, .. } => {
if need_flatten && inner_table.is_some() { if need_flatten && inner_table.is_some() {
return vec![Value::error( ShellError::UnsupportedInput( return vec![Value::error( ShellError::UnsupportedInput { msg: "can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(), input: "value originates from here".into(), msg_span: s, input_span: span }, span)
"can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(),
"value originates from here".into(),
s,
span
), span)
]; ];
} }

View File

@ -89,18 +89,18 @@ impl Command for Join {
let result = join(rows_1, rows_2, l_on, r_on, join_type, span); let result = join(rows_1, rows_2, l_on, r_on, join_type, span);
Ok(PipelineData::Value(result, None)) Ok(PipelineData::Value(result, None))
} }
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"(PipelineData<table>, table, string, string)".into(), msg: "(PipelineData<table>, table, string, string)".into(),
format!( input: format!(
"({:?}, {:?}, {:?} {:?})", "({:?}, {:?}, {:?} {:?})",
collected_input, collected_input,
table_2.get_type(), table_2.get_type(),
l_on.get_type(), l_on.get_type(),
r_on.get_type(), r_on.get_type(),
), ),
span, msg_span: span,
span, input_span: span,
)), }),
} }
} }
@ -126,12 +126,12 @@ fn join_type(call: &Call) -> Result<JoinType, nu_protocol::ShellError> {
(false, true, false, false) => Ok(JoinType::Left), (false, true, false, false) => Ok(JoinType::Left),
(false, false, true, false) => Ok(JoinType::Right), (false, false, true, false) => Ok(JoinType::Right),
(false, false, false, true) => Ok(JoinType::Outer), (false, false, false, true) => Ok(JoinType::Outer),
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"Choose one of: --inner, --left, --right, --outer".into(), msg: "Choose one of: --inner, --left, --right, --outer".into(),
"".into(), input: "".into(),
call.head, msg_span: call.head,
call.head, input_span: call.head,
)), }),
} }
} }

View File

@ -204,16 +204,9 @@ fn rename(
"already checked column to rename still exists", "already checked column to rename still exists",
); );
return Value::error( return Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput { msg: format!(
format!(
"The column '{not_exists_column}' does not exist in the input", "The column '{not_exists_column}' does not exist in the input",
), ), input: "value originated from here".into(), msg_span: head_span, input_span: span },
"value originated from here".into(),
// Arrow 1 points at the specified column name,
head_span,
// Arrow 2 points at the input value.
span,
),
span, span,
); );
} }

View File

@ -95,12 +95,12 @@ fn collect_binary(input: PipelineData, span: Span) -> Result<Vec<u8>, ShellError
} }
Some(Value::Error { error, .. }) => return Err(*error), Some(Value::Error { error, .. }) => return Err(*error),
Some(x) => { Some(x) => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Expected binary from pipeline".to_string(), msg: "Expected binary from pipeline".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
x.span(), input_span: x.span(),
)) })
} }
None => break, None => break,
} }
@ -117,13 +117,11 @@ fn from_ods(
let span = input.span(); let span = input.span();
let bytes = collect_binary(input, head)?; let bytes = collect_binary(input, head)?;
let buf: Cursor<Vec<u8>> = Cursor::new(bytes); let buf: Cursor<Vec<u8>> = Cursor::new(bytes);
let mut ods = Ods::<_>::new(buf).map_err(|_| { let mut ods = Ods::<_>::new(buf).map_err(|_| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Could not load ODS file".to_string(),
"Could not load ODS file".to_string(), input: "value originates from here".into(),
"value originates from here".into(), msg_span: head,
head, input_span: span.unwrap_or(head),
span.unwrap_or(head),
)
})?; })?;
let mut dict = IndexMap::new(); let mut dict = IndexMap::new();
@ -160,12 +158,12 @@ fn from_ods(
dict.insert(sheet_name, Value::list(sheet_output, head)); dict.insert(sheet_name, Value::list(sheet_output, head));
} else { } else {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Could not load sheet".to_string(), msg: "Could not load sheet".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span.unwrap_or(head), input_span: span.unwrap_or(head),
)); });
} }
} }

View File

@ -94,12 +94,12 @@ fn collect_binary(input: PipelineData, span: Span) -> Result<Vec<u8>, ShellError
bytes.extend_from_slice(&b); bytes.extend_from_slice(&b);
} }
Some(x) => { Some(x) => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Expected binary from pipeline".to_string(), msg: "Expected binary from pipeline".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
x.span(), input_span: x.span(),
)) })
} }
None => break, None => break,
} }
@ -116,13 +116,11 @@ fn from_xlsx(
let span = input.span(); let span = input.span();
let bytes = collect_binary(input, head)?; let bytes = collect_binary(input, head)?;
let buf: Cursor<Vec<u8>> = Cursor::new(bytes); let buf: Cursor<Vec<u8>> = Cursor::new(bytes);
let mut xlsx = Xlsx::<_>::new(buf).map_err(|_| { let mut xlsx = Xlsx::<_>::new(buf).map_err(|_| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Could not load XLSX file".to_string(),
"Could not load XLSX file".to_string(), input: "value originates from here".into(),
"value originates from here".into(), msg_span: head,
head, input_span: span.unwrap_or(head),
span.unwrap_or(head),
)
})?; })?;
let mut dict = IndexMap::new(); let mut dict = IndexMap::new();
@ -159,12 +157,12 @@ fn from_xlsx(
dict.insert(sheet_name, Value::list(sheet_output, head)); dict.insert(sheet_name, Value::list(sheet_output, head));
} else { } else {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Could not load sheet".to_string(), msg: "Could not load sheet".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span.unwrap_or(head), input_span: span.unwrap_or(head),
)); });
} }
} }

View File

@ -81,12 +81,12 @@ fn convert_yaml_value_to_nu_value(
span: Span, span: Span,
val_span: Span, val_span: Span,
) -> Result<Value, ShellError> { ) -> Result<Value, ShellError> {
let err_not_compatible_number = ShellError::UnsupportedInput( let err_not_compatible_number = ShellError::UnsupportedInput {
"Expected a nu-compatible number in YAML input".to_string(), msg: "Expected a nu-compatible number in YAML input".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
val_span, input_span: val_span,
); };
Ok(match v { Ok(match v {
serde_yaml::Value::Bool(b) => Value::bool(*b, span), serde_yaml::Value::Bool(b) => Value::bool(*b, span),
serde_yaml::Value::Number(n) if n.is_i64() => { serde_yaml::Value::Number(n) if n.is_i64() => {
@ -109,12 +109,12 @@ fn convert_yaml_value_to_nu_value(
for (k, v) in t { for (k, v) in t {
// A ShellError that we re-use multiple times in the Mapping scenario // A ShellError that we re-use multiple times in the Mapping scenario
let err_unexpected_map = ShellError::UnsupportedInput( let err_unexpected_map = ShellError::UnsupportedInput {
format!("Unexpected YAML:\nKey: {k:?}\nValue: {v:?}"), msg: format!("Unexpected YAML:\nKey: {k:?}\nValue: {v:?}"),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
val_span, input_span: val_span,
); };
match (k, v) { match (k, v) {
(serde_yaml::Value::Number(k), _) => { (serde_yaml::Value::Number(k), _) => {
collected.insert( collected.insert(
@ -198,14 +198,13 @@ pub fn from_yaml_string_to_value(
let mut documents = vec![]; let mut documents = vec![];
for document in serde_yaml::Deserializer::from_str(&s) { for document in serde_yaml::Deserializer::from_str(&s) {
let v: serde_yaml::Value = serde_yaml::Value::deserialize(document).map_err(|x| { let v: serde_yaml::Value =
ShellError::UnsupportedInput( serde_yaml::Value::deserialize(document).map_err(|x| ShellError::UnsupportedInput {
format!("Could not load YAML: {x}"), msg: format!("Could not load YAML: {x}"),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
val_span, input_span: val_span,
) })?;
})?;
documents.push(convert_yaml_value_to_nu_value(&v, span, val_span)?); documents.push(convert_yaml_value_to_nu_value(&v, span, val_span)?);
} }

View File

@ -126,12 +126,12 @@ fn to_string_tagged_value(
} }
fn make_unsupported_input_error(value: &Value, head: Span, span: Span) -> ShellError { fn make_unsupported_input_error(value: &Value, head: Span, span: Span) -> ShellError {
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"Unexpected type".to_string(), msg: "Unexpected type".to_string(),
format!("input type: {:?}", value.get_type()), input: format!("input type: {:?}", value.get_type()),
head, msg_span: head,
span, input_span: span,
) }
} }
pub fn find_non_record(values: &[Value]) -> Option<&Value> { pub fn find_non_record(values: &[Value]) -> Option<&Value> {

View File

@ -131,28 +131,28 @@ pub fn value_to_string(
let mut s = String::with_capacity(2 * val.len()); let mut s = String::with_capacity(2 * val.len());
for byte in val { for byte in val {
if write!(s, "{byte:02X}").is_err() { if write!(s, "{byte:02X}").is_err() {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"could not convert binary to string".into(), msg: "could not convert binary to string".into(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
v.span(), input_span: v.span(),
)); });
} }
} }
Ok(format!("0x[{s}]")) Ok(format!("0x[{s}]"))
} }
Value::Block { .. } => Err(ShellError::UnsupportedInput( Value::Block { .. } => Err(ShellError::UnsupportedInput {
"blocks are currently not nuon-compatible".into(), msg: "blocks are currently not nuon-compatible".into(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
v.span(), input_span: v.span(),
)), }),
Value::Closure { .. } => Err(ShellError::UnsupportedInput( Value::Closure { .. } => Err(ShellError::UnsupportedInput {
"closures are currently not nuon-compatible".into(), msg: "closures are currently not nuon-compatible".into(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
v.span(), input_span: v.span(),
)), }),
Value::Bool { val, .. } => { Value::Bool { val, .. } => {
if *val { if *val {
Ok("true".to_string()) Ok("true".to_string())
@ -160,18 +160,18 @@ pub fn value_to_string(
Ok("false".to_string()) Ok("false".to_string())
} }
} }
Value::CellPath { .. } => Err(ShellError::UnsupportedInput( Value::CellPath { .. } => Err(ShellError::UnsupportedInput {
"cell-paths are currently not nuon-compatible".to_string(), msg: "cell-paths are currently not nuon-compatible".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
v.span(), input_span: v.span(),
)), }),
Value::CustomValue { .. } => Err(ShellError::UnsupportedInput( Value::CustomValue { .. } => Err(ShellError::UnsupportedInput {
"custom values are currently not nuon-compatible".to_string(), msg: "custom values are currently not nuon-compatible".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
v.span(), input_span: v.span(),
)), }),
Value::Date { val, .. } => Ok(val.to_rfc3339()), Value::Date { val, .. } => Ok(val.to_rfc3339()),
// FIXME: make durations use the shortest lossless representation. // FIXME: make durations use the shortest lossless representation.
Value::Duration { val, .. } => Ok(format!("{}ns", *val)), Value::Duration { val, .. } => Ok(format!("{}ns", *val)),
@ -241,12 +241,12 @@ pub fn value_to_string(
)) ))
} }
} }
Value::MatchPattern { .. } => Err(ShellError::UnsupportedInput( Value::MatchPattern { .. } => Err(ShellError::UnsupportedInput {
"match patterns are currently not nuon-compatible".to_string(), msg: "match patterns are currently not nuon-compatible".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
span, msg_span: span,
v.span(), input_span: v.span(),
)), }),
Value::Nothing { .. } => Ok("null".to_string()), Value::Nothing { .. } => Ok("null".to_string()),
Value::Range { val, .. } => Ok(format!( Value::Range { val, .. } => Ok(format!(
"{}..{}{}", "{}..{}{}",

View File

@ -137,12 +137,12 @@ fn value_to_toml_value(
Value::Record { .. } => helper(engine_state, v), Value::Record { .. } => helper(engine_state, v),
// Propagate existing errors // Propagate existing errors
Value::Error { error, .. } => Err(*error.clone()), Value::Error { error, .. } => Err(*error.clone()),
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
format!("{:?} is not valid top-level TOML", v.get_type()), msg: format!("{:?} is not valid top-level TOML", v.get_type()),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
v.span(), input_span: v.span(),
)), }),
} }
} }

View File

@ -50,12 +50,12 @@ impl Command for SubCommand {
let base: Spanned<f64> = call.req(engine_state, stack, 0)?; let base: Spanned<f64> = call.req(engine_state, stack, 0)?;
if base.item <= 0.0f64 { if base.item <= 0.0f64 {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Base has to be greater 0".into(), msg: "Base has to be greater 0".into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
base.span, input_span: base.span,
)); });
} }
// This doesn't match explicit nulls // This doesn't match explicit nulls
if matches!(input, PipelineData::Empty) { if matches!(input, PipelineData::Empty) {
@ -103,13 +103,13 @@ fn operate(value: Value, head: Span, base: f64) -> Value {
if val <= 0.0 { if val <= 0.0 {
return Value::error( return Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"'math log' undefined for values outside the open interval (0, Inf)." msg: "'math log' undefined for values outside the open interval (0, Inf)."
.into(), .into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
), },
span, span,
); );
} }

View File

@ -107,14 +107,14 @@ pub fn median(values: &[Value], span: Span, head: Span) -> Result<Value, ShellEr
match take { match take {
Pick::Median => { Pick::Median => {
let idx = (values.len() as f64 / 2.0).floor() as usize; let idx = (values.len() as f64 / 2.0).floor() as usize;
let out = sorted.get(idx).ok_or_else(|| { let out = sorted
ShellError::UnsupportedInput( .get(idx)
"Empty input".to_string(), .ok_or_else(|| ShellError::UnsupportedInput {
"value originates from here".into(), msg: "Empty input".to_string(),
head, input: "value originates from here".into(),
span, msg_span: head,
) input_span: span,
})?; })?;
Ok(out.clone()) Ok(out.clone())
} }
Pick::MedianAverage => { Pick::MedianAverage => {
@ -123,25 +123,21 @@ pub fn median(values: &[Value], span: Span, head: Span) -> Result<Value, ShellEr
let left = sorted let left = sorted
.get(idx_start) .get(idx_start)
.ok_or_else(|| { .ok_or_else(|| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Empty input".to_string(),
"Empty input".to_string(), input: "value originates from here".into(),
"value originates from here".into(), msg_span: head,
head, input_span: span,
span,
)
})? })?
.clone(); .clone();
let right = sorted let right = sorted
.get(idx_end) .get(idx_end)
.ok_or_else(|| { .ok_or_else(|| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Empty input".to_string(),
"Empty input".to_string(), input: "value originates from here".into(),
"value originates from here".into(), msg_span: head,
head, input_span: span,
span,
)
})? })?
.clone(); .clone();

View File

@ -138,12 +138,12 @@ pub fn mode(values: &[Value], _span: Span, head: Span) -> Result<Value, ShellErr
Ok(HashableType::new(val.to_ne_bytes(), NumberTypes::Filesize)) Ok(HashableType::new(val.to_ne_bytes(), NumberTypes::Filesize))
} }
Value::Error { error, .. } => Err(*error.clone()), Value::Error { error, .. } => Err(*error.clone()),
other => Err(ShellError::UnsupportedInput( other => Err(ShellError::UnsupportedInput {
"Unable to give a result with this input".to_string(), msg: "Unable to give a result with this input".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
other.span(), input_span: other.span(),
)), }),
}) })
.collect::<Result<Vec<HashableType>, ShellError>>()?; .collect::<Result<Vec<HashableType>, ShellError>>()?;

View File

@ -23,13 +23,11 @@ pub fn reducer_for(command: Reduce) -> ReducerFunction {
pub fn max(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError> { pub fn max(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError> {
let mut biggest = data let mut biggest = data
.first() .first()
.ok_or_else(|| { .ok_or_else(|| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Empty input".to_string(),
"Empty input".to_string(), input: "value originates from here".into(),
"value originates from here".into(), msg_span: head,
head, input_span: span,
span,
)
})? })?
.clone(); .clone();
@ -54,13 +52,11 @@ pub fn max(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError
pub fn min(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError> { pub fn min(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError> {
let mut smallest = data let mut smallest = data
.first() .first()
.ok_or_else(|| { .ok_or_else(|| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Empty input".to_string(),
"Empty input".to_string(), input: "value originates from here".into(),
"value originates from here".into(), msg_span: head,
head, input_span: span,
span,
)
})? })?
.clone(); .clone();
@ -96,12 +92,12 @@ pub fn sum(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError
} }
} }
None => Err(ShellError::UnsupportedInput( None => Err(ShellError::UnsupportedInput {
"Empty input".to_string(), msg: "Empty input".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
)), }),
}?; }?;
for value in &data { for value in &data {
@ -114,12 +110,13 @@ pub fn sum(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError
} }
Value::Error { error, .. } => return Err(*error.clone()), Value::Error { error, .. } => return Err(*error.clone()),
other => { other => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Attempted to compute the sum of a value that cannot be summed".to_string(), msg: "Attempted to compute the sum of a value that cannot be summed"
"value originates from here".into(), .to_string(),
head, input: "value originates from here".into(),
other.span(), msg_span: head,
)); input_span: other.span(),
});
} }
} }
} }
@ -137,12 +134,12 @@ pub fn product(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellE
_ => Ok(Value::nothing(head)), _ => Ok(Value::nothing(head)),
} }
} }
None => Err(ShellError::UnsupportedInput( None => Err(ShellError::UnsupportedInput {
"Empty input".to_string(), msg: "Empty input".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
)), }),
}?; }?;
for value in &data { for value in &data {
@ -152,13 +149,13 @@ pub fn product(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellE
} }
Value::Error { error, .. } => return Err(*error.clone()), Value::Error { error, .. } => return Err(*error.clone()),
other => { other => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Attempted to compute the product of a value that cannot be multiplied" msg: "Attempted to compute the product of a value that cannot be multiplied"
.to_string(), .to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
other.span(), input_span: other.span(),
)); });
} }
} }
} }

View File

@ -93,12 +93,12 @@ fn operate(value: Value, head: Span) -> Value {
fn error_negative_sqrt(head: Span, span: Span) -> Value { fn error_negative_sqrt(head: Span, span: Span) -> Value {
Value::error( Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
String::from("Can't square root a negative number"), msg: String::from("Can't square root a negative number"),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
), },
span, span,
) )
} }

View File

@ -49,12 +49,12 @@ fn helper_for_tables(
} }
} }
if column_totals.keys().len() == 0 { if column_totals.keys().len() == 0 {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Unable to give a result with this input".to_string(), msg: "Unable to give a result with this input".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
name, msg_span: name,
val_span, input_span: val_span,
)); });
} }
Ok(Value::record(column_totals.into_iter().collect(), name)) Ok(Value::record(column_totals.into_iter().collect(), name))
@ -107,13 +107,13 @@ pub fn calculate(
} }
PipelineData::Value(val, ..) => mf(&[val], span, name), PipelineData::Value(val, ..) => mf(&[val], span, name),
PipelineData::Empty { .. } => Err(ShellError::PipelineEmpty { dst_span: name }), PipelineData::Empty { .. } => Err(ShellError::PipelineEmpty { dst_span: name }),
val => Err(ShellError::UnsupportedInput( val => Err(ShellError::UnsupportedInput {
"Only ints, floats, lists, records, or ranges are supported".into(), msg: "Only ints, floats, lists, records, or ranges are supported".into(),
"value originates from here".into(), input: "value originates from here".into(),
name, msg_span: name,
// This requires both the ListStream and Empty match arms to be above it. input_span: val
val.span() .span()
.expect("non-Empty non-ListStream PipelineData had no span"), .expect("non-Empty non-ListStream PipelineData had no span"),
)), }),
} }
} }

View File

@ -65,12 +65,13 @@ fn sum_of_squares(values: &[Value], span: Span) -> Result<Value, ShellError> {
let v = match &value { let v = match &value {
Value::Int { .. } | Value::Float { .. } => Ok(value), Value::Int { .. } | Value::Float { .. } => Ok(value),
Value::Error { error, .. } => Err(*error.clone()), Value::Error { error, .. } => Err(*error.clone()),
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"Attempted to compute the sum of squares of a non-int, non-float value".to_string(), msg: "Attempted to compute the sum of squares of a non-int, non-float value"
"value originates from here".into(), .to_string(),
span, input: "value originates from here".into(),
value.span(), msg_span: span,
)), input_span: value.span(),
}),
}?; }?;
let v_squared = &v.mul(span, v, span)?; let v_squared = &v.mul(span, v, span)?;
sum_x2 = sum_x2.add(span, v_squared, span)?; sum_x2 = sum_x2.add(span, v_squared, span)?;

View File

@ -56,13 +56,8 @@ pub fn http_parse_url(
let url = match url::Url::parse(&requested_url) { let url = match url::Url::parse(&requested_url) {
Ok(u) => u, Ok(u) => u,
Err(_e) => { Err(_e) => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput { msg: "Incomplete or incorrect URL. Expected a full URL, e.g., https://www.example.com"
"Incomplete or incorrect URL. Expected a full URL, e.g., https://www.example.com" .to_string(), input: format!("value: '{requested_url:?}'"), msg_span: call.head, input_span: span });
.to_string(),
format!("value: '{requested_url:?}'"),
call.head,
span,
));
} }
}; };

View File

@ -75,12 +75,12 @@ fn to_url(input: PipelineData, head: Span) -> Result<PipelineData, ShellError> {
row_vec.push((k.clone(), s.to_string())); row_vec.push((k.clone(), s.to_string()));
} }
_ => { _ => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Expected a record with string values".to_string(), msg: "Expected a record with string values".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
)); });
} }
} }
} }
@ -97,12 +97,12 @@ fn to_url(input: PipelineData, head: Span) -> Result<PipelineData, ShellError> {
} }
// Propagate existing errors // Propagate existing errors
Value::Error { error, .. } => Err(*error), Value::Error { error, .. } => Err(*error),
other => Err(ShellError::UnsupportedInput( other => Err(ShellError::UnsupportedInput {
"Expected a table from pipeline".to_string(), msg: "Expected a table from pipeline".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
other.span(), input_span: other.span(),
)), }),
} }
}) })
.collect(); .collect();

View File

@ -104,12 +104,12 @@ impl Command for SubCommand {
url_components?.to_url(span) url_components?.to_url(span)
} }
Value::Error { error, .. } => Err(*error), Value::Error { error, .. } => Err(*error),
other => Err(ShellError::UnsupportedInput( other => Err(ShellError::UnsupportedInput {
"Expected a record from pipeline".to_string(), msg: "Expected a record from pipeline".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
other.span(), input_span: other.span(),
)), }),
} }
}) })
.collect(); .collect();

View File

@ -113,21 +113,21 @@ fn parse(value: Value, head: Span, engine_state: &EngineState) -> Result<Pipelin
Ok(PipelineData::Value(Value::record(record, head), None)) Ok(PipelineData::Value(Value::record(record, head), None))
} }
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"String not compatible with url-encoding".to_string(), msg: "String not compatible with url-encoding".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
)), }),
} }
} }
Err(_e) => Err(ShellError::UnsupportedInput( Err(_e) => Err(ShellError::UnsupportedInput {
"Incomplete or incorrect URL. Expected a full URL, e.g., https://www.example.com" msg: "Incomplete or incorrect URL. Expected a full URL, e.g., https://www.example.com"
.to_string(), .to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
)), }),
} }
} }

View File

@ -180,12 +180,12 @@ fn run(call: &Call, args: &Arguments, input: PipelineData) -> Result<PipelineDat
metadata, metadata,
)), )),
PipelineData::Empty { .. } => Err(ShellError::PipelineEmpty { dst_span: head }), PipelineData::Empty { .. } => Err(ShellError::PipelineEmpty { dst_span: head }),
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"Input value cannot be joined".to_string(), msg: "Input value cannot be joined".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
input.span().unwrap_or(call.head), input_span: input.span().unwrap_or(call.head),
)), }),
} }
} }
@ -249,14 +249,9 @@ fn merge_record(record: &Record, head: Span, span: Span) -> Result<PathBuf, Shel
for key in &record.cols { for key in &record.cols {
if !super::ALLOWED_COLUMNS.contains(&key.as_str()) { if !super::ALLOWED_COLUMNS.contains(&key.as_str()) {
let allowed_cols = super::ALLOWED_COLUMNS.join(", "); let allowed_cols = super::ALLOWED_COLUMNS.join(", ");
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput { msg: format!(
format!(
"Column '{key}' is not valid for a structured path. Allowed columns on this platform are: {allowed_cols}" "Column '{key}' is not valid for a structured path. Allowed columns on this platform are: {allowed_cols}"
), ), input: "value originates from here".into(), msg_span: head, input_span: span });
"value originates from here".into(),
head,
span
));
} }
} }

View File

@ -73,12 +73,12 @@ impl Command for Input {
}); });
if numchar.item < 1 { if numchar.item < 1 {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Number of characters to read has to be positive".to_string(), msg: "Number of characters to read has to be positive".to_string(),
"value originated from here".to_string(), input: "value originated from here".to_string(),
call.head, msg_span: call.head,
numchar.span, input_span: numchar.span,
)); });
} }
if let Some(prompt) = &prompt { if let Some(prompt) = &prompt {

View File

@ -178,21 +178,21 @@ impl EventTypeFilter {
} }
fn wrong_type_error(head: Span, val: &str, val_span: Span) -> ShellError { fn wrong_type_error(head: Span, val: &str, val_span: Span) -> ShellError {
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
format!("{} is not a valid event type", val), msg: format!("{} is not a valid event type", val),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
val_span, input_span: val_span,
) }
} }
fn bad_list_error(head: Span, value: &Value) -> ShellError { fn bad_list_error(head: Span, value: &Value) -> ShellError {
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"--types expects a list of strings".to_string(), msg: "--types expects a list of strings".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
value.span(), input_span: value.span(),
) }
} }
/// Enable capturing of all events allowed by this filter. /// Enable capturing of all events allowed by this filter.

View File

@ -127,13 +127,12 @@ fn action(
Value::string(std::str::from_utf8(&enc_vec).unwrap_or(""), command_span) Value::string(std::str::from_utf8(&enc_vec).unwrap_or(""), command_span)
} }
ActionType::Decode => Value::error( ActionType::Decode => Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"Binary data can only be encoded".to_string(), msg: "Binary data can only be encoded".to_string(),
"value originates from here".into(), input: "value originates from here".into(),
command_span, msg_span: command_span,
// This line requires the Value::Error {} match above. input_span: input.span(),
input.span(), },
),
command_span, command_span,
), ),
}, },

View File

@ -99,12 +99,12 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"#
} }
// This should be more precise, but due to difficulties in getting spans // This should be more precise, but due to difficulties in getting spans
// from PipelineData::ListData, this is as it is. // from PipelineData::ListData, this is as it is.
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"non-binary input".into(), msg: "non-binary input".into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
input.span().unwrap_or(head), input_span: input.span().unwrap_or(head),
)), }),
} }
} }
} }

View File

@ -113,12 +113,12 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"#
} }
// This should be more precise, but due to difficulties in getting spans // This should be more precise, but due to difficulties in getting spans
// from PipelineData::ListStream, this is as it is. // from PipelineData::ListStream, this is as it is.
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput {
"non-string input".into(), msg: "non-string input".into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
input.span().unwrap_or(head), input_span: input.span().unwrap_or(head),
)), }),
} }
} }
} }

View File

@ -12,12 +12,12 @@ pub fn detect_encoding_name(
//Guess(TLD=None(usually used in HTML), Allow_UTF8=True) //Guess(TLD=None(usually used in HTML), Allow_UTF8=True)
let (encoding, is_certain) = detector.guess_assess(None, true); let (encoding, is_certain) = detector.guess_assess(None, true);
if !is_certain { if !is_certain {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"Input contains unknown encoding, try giving a encoding name".into(), msg: "Input contains unknown encoding, try giving a encoding name".into(),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
input, input_span: input,
)); });
} }
Ok(encoding) Ok(encoding)
} }

View File

@ -191,13 +191,12 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value {
// Propagate errors by explicitly matching them before the final case. // Propagate errors by explicitly matching them before the final case.
Value::Error { .. } => input.clone(), Value::Error { .. } => input.clone(),
other => Value::error( other => Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
"Only string values are supported".into(), msg: "Only string values are supported".into(),
format!("input type: {:?}", other.get_type()), input: format!("input type: {:?}", other.get_type()),
head, msg_span: head,
// This line requires the Value::Error match above. input_span: other.span(),
other.span(), },
),
head, head,
), ),
} }

View File

@ -198,18 +198,15 @@ fn action(input: &Value, arg: &Arguments, head: Span) -> Value {
} }
_ => input.clone(), _ => input.clone(),
}, },
ActionMode::Local => { ActionMode::Local => Value::error(
Value::error( ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: "Only string values are supported".into(),
"Only string values are supported".into(), input: format!("input type: {:?}", other.get_type()),
format!("input type: {:?}", other.get_type()), msg_span: head,
head, input_span: other.span(),
// This line requires the Value::Error match above. },
other.span(), head,
), ),
head,
)
}
} }
} }
} }

View File

@ -627,12 +627,14 @@ pub enum ShellError {
/// This error is fairly generic. Refer to the specific error message for further details. /// This error is fairly generic. Refer to the specific error message for further details.
#[error("Unsupported input")] #[error("Unsupported input")]
#[diagnostic(code(nu::shell::unsupported_input))] #[diagnostic(code(nu::shell::unsupported_input))]
UnsupportedInput( UnsupportedInput {
String, msg: String,
String, input: String,
#[label("{0}")] Span, // call head (the name of the command itself) #[label("{msg}")]
#[label("input type: {1}")] Span, msg_span: Span,
), #[label("{input}")]
input_span: Span,
},
/// Failed to parse an input into a datetime value. /// Failed to parse an input into a datetime value.
/// ///

View File

@ -1659,12 +1659,12 @@ impl Value {
// SIGH... // SIGH...
Value::Error { error, .. } => return Err(*error.clone()), Value::Error { error, .. } => return Err(*error.clone()),
_ => { _ => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"expected table or record".into(), msg: "expected table or record".into(),
format!("input type: {:?}", val.get_type()), input: format!("input type: {:?}", val.get_type()),
head_span, msg_span: head_span,
*span, input_span: *span,
)) })
} }
} }
} }
@ -1697,12 +1697,12 @@ impl Value {
*self = record *self = record
} }
other => { other => {
return Err(ShellError::UnsupportedInput( return Err(ShellError::UnsupportedInput {
"table or record".into(), msg: "table or record".into(),
format!("input type: {:?}", other.get_type()), input: format!("input type: {:?}", other.get_type()),
head_span, msg_span: head_span,
*span, input_span: *span,
)) })
} }
}, },
PathMember::Int { PathMember::Int {
@ -3220,27 +3220,24 @@ impl Value {
if let Some(regex) = cache.get(rhs) { if let Some(regex) = cache.get(rhs) {
regex.is_match(lhs) regex.is_match(lhs)
} else { } else {
let regex = Regex::new(rhs).map_err(|e| { let regex =
ShellError::UnsupportedInput( Regex::new(rhs).map_err(|e| ShellError::UnsupportedInput {
format!("{e}"), msg: format!("{e}"),
"value originated from here".into(), input: "value originated from here".into(),
span, msg_span: span,
rhs_span, input_span: rhs_span,
) })?;
})?;
let ret = regex.is_match(lhs); let ret = regex.is_match(lhs);
cache.put(rhs.clone(), regex); cache.put(rhs.clone(), regex);
ret ret
} }
} }
Err(_) => { Err(_) => {
let regex = Regex::new(rhs).map_err(|e| { let regex = Regex::new(rhs).map_err(|e| ShellError::UnsupportedInput {
ShellError::UnsupportedInput( msg: format!("{e}"),
format!("{e}"), input: "value originated from here".into(),
"value originated from here".into(), msg_span: span,
span, input_span: rhs_span,
rhs_span,
)
})?; })?;
regex.is_match(lhs) regex.is_match(lhs)
} }

View File

@ -36,12 +36,12 @@ pub fn from_ics_call(call: &EvaluatedCall, input: &Value) -> Result<Value, Label
match calendar { match calendar {
Ok(c) => output.push(calendar_to_value(c, head)), Ok(c) => output.push(calendar_to_value(c, head)),
Err(e) => output.push(Value::error( Err(e) => output.push(Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
format!("input cannot be parsed as .ics ({e})"), msg: format!("input cannot be parsed as .ics ({e})"),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
), },
span, span,
)), )),
} }

View File

@ -40,12 +40,12 @@ pub fn from_ini_call(call: &EvaluatedCall, input: &Value) -> Result<Value, Label
// all sections with all its key value pairs // all sections with all its key value pairs
Ok(Value::record(sections, span)) Ok(Value::record(sections, span))
} }
Err(err) => Err(ShellError::UnsupportedInput( Err(err) => Err(ShellError::UnsupportedInput {
format!("Could not load ini: {err}"), msg: format!("Could not load ini: {err}"),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
) }
.into()), .into()),
} }
} }

View File

@ -32,12 +32,12 @@ pub fn from_vcf_call(call: &EvaluatedCall, input: &Value) -> Result<Value, Label
let iter = parser.map(move |contact| match contact { let iter = parser.map(move |contact| match contact {
Ok(c) => contact_to_value(c, head), Ok(c) => contact_to_value(c, head),
Err(e) => Value::error( Err(e) => Value::error(
ShellError::UnsupportedInput( ShellError::UnsupportedInput {
format!("input cannot be parsed as .vcf ({e})"), msg: format!("input cannot be parsed as .vcf ({e})"),
"value originates from here".into(), input: "value originates from here".into(),
head, msg_span: head,
span, input_span: span,
), },
span, span,
), ),
}); });