mirror of
https://github.com/nushell/nushell.git
synced 2025-01-11 00:38:23 +01:00
Box ShellError
in Value::Error
(#8375)
# Description Our `ShellError` at the moment has a `std::mem::size_of<ShellError>` of 136 bytes (on AMD64). As a result `Value` directly storing the struct also required 136 bytes (thanks to alignment requirements). This change stores the `Value::Error` `ShellError` on the heap. Pro: - Value now needs just 80 bytes - Should be 1 cacheline less (still at least 2 cachelines) Con: - More small heap allocations when dealing with `Value::Error` - More heap fragmentation - Potential for additional required memcopies # Further code changes Includes a small refactor of `try` due to a type mismatch in its large match. # User-Facing Changes None for regular users. Plugin authors may have to update their matches on `Value` if they use `nu-protocol` Needs benchmarking to see if there is a benefit in real world workloads. **Update** small improvements in runtime for workloads with high volume of values. Significant reduction in maximum resident set size, when many values are held in memory. # Tests + Formatting
This commit is contained in:
parent
c26d91fb61
commit
a52386e837
@ -145,7 +145,7 @@ pub(crate) fn print_table_or_error(
|
|||||||
|
|
||||||
if let PipelineData::Value(Value::Error { error }, ..) = &pipeline_data {
|
if let PipelineData::Value(Value::Error { error }, ..) = &pipeline_data {
|
||||||
let working_set = StateWorkingSet::new(engine_state);
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
report_error(&working_set, error);
|
report_error(&working_set, &**error);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ fn print_or_exit(pipeline_data: PipelineData, engine_state: &mut EngineState, co
|
|||||||
if let Value::Error { error } = item {
|
if let Value::Error { error } = item {
|
||||||
let working_set = StateWorkingSet::new(engine_state);
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
|
|
||||||
report_error(&working_set, &error);
|
report_error(&working_set, &*error);
|
||||||
|
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,9 @@ impl Command for NuHighlight {
|
|||||||
span: head,
|
span: head,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Value::Error { error: err },
|
Err(err) => Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ctrlc,
|
ctrlc,
|
||||||
)
|
)
|
||||||
|
@ -1124,7 +1124,7 @@ fn run_hook_block(
|
|||||||
eval_block_with_early_return(engine_state, &mut callee_stack, block, input, false, false)?;
|
eval_block_with_early_return(engine_state, &mut callee_stack, block, input, false, false)?;
|
||||||
|
|
||||||
if let PipelineData::Value(Value::Error { error }, _) = pipeline_data {
|
if let PipelineData::Value(Value::Error { error }, _) = pipeline_data {
|
||||||
return Err(error);
|
return Err(*error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all went fine, preserve the environment of the called block
|
// If all went fine, preserve the environment of the called block
|
||||||
|
@ -57,66 +57,29 @@ impl Command for Try {
|
|||||||
let result = eval_block(engine_state, stack, try_block, input, false, false);
|
let result = eval_block(engine_state, stack, try_block, input, false, false);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Err(error) | Ok(PipelineData::Value(Value::Error { error }, ..)) => {
|
Err(error) => {
|
||||||
if let nu_protocol::ShellError::Break(_) = error {
|
let error = intercept_block_control(error)?;
|
||||||
return Err(error);
|
let err_value = Value::Error {
|
||||||
} else if let nu_protocol::ShellError::Continue(_) = error {
|
error: Box::new(error),
|
||||||
return Err(error);
|
};
|
||||||
} else if let nu_protocol::ShellError::Return(_, _) = error {
|
handle_catch(err_value, catch_block, engine_state, stack)
|
||||||
return Err(error);
|
}
|
||||||
}
|
Ok(PipelineData::Value(Value::Error { error }, ..)) => {
|
||||||
if let Some(catch_block) = catch_block {
|
let error = intercept_block_control(*error)?;
|
||||||
let catch_block = engine_state.get_block(catch_block.block_id);
|
let err_value = Value::Error {
|
||||||
let err_value = Value::Error { error };
|
error: Box::new(error),
|
||||||
// Put the error value in the positional closure var
|
};
|
||||||
if let Some(var) = catch_block.signature.get_positional(0) {
|
handle_catch(err_value, catch_block, engine_state, stack)
|
||||||
if let Some(var_id) = &var.var_id {
|
|
||||||
stack.add_var(*var_id, err_value.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_block(
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
catch_block,
|
|
||||||
// Make the error accessible with $in, too
|
|
||||||
err_value.into_pipeline_data(),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Ok(PipelineData::empty())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// external command may fail to run
|
// external command may fail to run
|
||||||
Ok(pipeline) => {
|
Ok(pipeline) => {
|
||||||
let (pipeline, external_failed) = pipeline.is_external_failed();
|
let (pipeline, external_failed) = pipeline.is_external_failed();
|
||||||
if external_failed {
|
if external_failed {
|
||||||
if let Some(catch_block) = catch_block {
|
// Because external command errors aren't "real" errors,
|
||||||
let catch_block = engine_state.get_block(catch_block.block_id);
|
// (unless do -c is in effect)
|
||||||
|
// they can't be passed in as Nushell values.
|
||||||
if let Some(var) = catch_block.signature.get_positional(0) {
|
let err_value = Value::nothing(call.head);
|
||||||
if let Some(var_id) = &var.var_id {
|
handle_catch(err_value, catch_block, engine_state, stack)
|
||||||
// Because external command errors aren't "real" errors,
|
|
||||||
// (unless do -c is in effect)
|
|
||||||
// they can't be passed in as Nushell values.
|
|
||||||
let err_value = Value::nothing(call.head);
|
|
||||||
stack.add_var(*var_id, err_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_block(
|
|
||||||
engine_state,
|
|
||||||
stack,
|
|
||||||
catch_block,
|
|
||||||
// The same null as in the above block is set as the $in value.
|
|
||||||
Value::nothing(call.head).into_pipeline_data(),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Ok(PipelineData::empty())
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Ok(pipeline)
|
Ok(pipeline)
|
||||||
}
|
}
|
||||||
@ -140,6 +103,48 @@ impl Command for Try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_catch(
|
||||||
|
err_value: Value,
|
||||||
|
catch_block: Option<Closure>,
|
||||||
|
engine_state: &EngineState,
|
||||||
|
stack: &mut Stack,
|
||||||
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
if let Some(catch_block) = catch_block {
|
||||||
|
let catch_block = engine_state.get_block(catch_block.block_id);
|
||||||
|
// Put the error value in the positional closure var
|
||||||
|
if let Some(var) = catch_block.signature.get_positional(0) {
|
||||||
|
if let Some(var_id) = &var.var_id {
|
||||||
|
stack.add_var(*var_id, err_value.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_block(
|
||||||
|
engine_state,
|
||||||
|
stack,
|
||||||
|
catch_block,
|
||||||
|
// Make the error accessible with $in, too
|
||||||
|
err_value.into_pipeline_data(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Ok(PipelineData::empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The flow control commands `break`/`continue`/`return` emit their own [`ShellError`] variants
|
||||||
|
/// We need to ignore those in `try` and bubble them through
|
||||||
|
///
|
||||||
|
/// `Err` when flow control to bubble up with `?`
|
||||||
|
fn intercept_block_control(error: ShellError) -> Result<ShellError, ShellError> {
|
||||||
|
match error {
|
||||||
|
nu_protocol::ShellError::Break(_) => Err(error),
|
||||||
|
nu_protocol::ShellError::Continue(_) => Err(error),
|
||||||
|
nu_protocol::ShellError::Return(_, _) => Err(error),
|
||||||
|
_ => Ok(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -81,12 +81,12 @@ fn operate(value: Value, target: i64, 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 { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,12 +150,12 @@ fn operate(value: Value, head: Span, signed: bool, number_size: NumberBytes) ->
|
|||||||
// Propagate errors inside the value
|
// Propagate errors inside the value
|
||||||
Value::Error { .. } => other,
|
Value::Error { .. } => other,
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -81,12 +81,12 @@ fn operate(value: Value, target: i64, 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 { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ where
|
|||||||
match rotate_result {
|
match rotate_result {
|
||||||
Ok(val) => Value::Int { val, span },
|
Ok(val) => Value::Int { val, span },
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
"Rotate left result beyond the range of 64 bit signed number".to_string(),
|
"Rotate left result beyond the range of 64 bit signed number".to_string(),
|
||||||
format!(
|
format!(
|
||||||
"{val} of the specified number of bytes rotate left {bits} bits exceed limit"
|
"{val} of the specified number of bytes rotate left {bits} bits exceed limit"
|
||||||
@ -111,7 +111,7 @@ where
|
|||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,12 +137,12 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ where
|
|||||||
match rotate_result {
|
match rotate_result {
|
||||||
Ok(val) => Value::Int { val, span },
|
Ok(val) => Value::Int { val, span },
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
"Rotate right result beyond the range of 64 bit signed number".to_string(),
|
"Rotate right result beyond the range of 64 bit signed number".to_string(),
|
||||||
format!(
|
format!(
|
||||||
"{val} of the specified number of bytes rotate right {bits} bits exceed limit"
|
"{val} of the specified number of bytes rotate right {bits} bits exceed limit"
|
||||||
@ -115,7 +115,7 @@ where
|
|||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,12 +141,12 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ where
|
|||||||
match shift_result {
|
match shift_result {
|
||||||
Ok(val) => Value::Int { val, span },
|
Ok(val) => Value::Int { val, span },
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
"Shift left result beyond the range of 64 bit signed number".to_string(),
|
"Shift left result beyond the range of 64 bit signed number".to_string(),
|
||||||
format!(
|
format!(
|
||||||
"{val} of the specified number of bytes shift left {bits} bits exceed limit"
|
"{val} of the specified number of bytes shift left {bits} bits exceed limit"
|
||||||
@ -123,18 +123,18 @@ where
|
|||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Value::Error {
|
None => Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
"Shift left failed".to_string(),
|
"Shift left failed".to_string(),
|
||||||
format!("{val} shift left {bits} bits failed, you may shift too many bits"),
|
format!("{val} shift left {bits} bits failed, you may shift too many bits"),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,12 +160,12 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ where
|
|||||||
match shift_result {
|
match shift_result {
|
||||||
Ok(val) => Value::Int { val, span },
|
Ok(val) => Value::Int { val, span },
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
"Shift right result beyond the range of 64 bit signed number".to_string(),
|
"Shift right result beyond the range of 64 bit signed number".to_string(),
|
||||||
format!(
|
format!(
|
||||||
"{val} of the specified number of bytes shift right {bits} bits exceed limit"
|
"{val} of the specified number of bytes shift right {bits} bits exceed limit"
|
||||||
@ -113,18 +113,18 @@ where
|
|||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Value::Error {
|
None => Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
"Shift right failed".to_string(),
|
"Shift right failed".to_string(),
|
||||||
format!("{val} shift right {bits} bits failed, you may shift too many bits"),
|
format!("{val} shift right {bits} bits failed, you may shift too many bits"),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,12 +150,12 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,12 +80,12 @@ fn operate(value: Value, target: i64, 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 { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer".into(),
|
exp_input_type: "integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,12 +125,12 @@ fn add(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ fn parse_range(range: Value, head: Span) -> Result<(isize, isize, Span), ShellEr
|
|||||||
Value::Int { val, .. } => val.to_string(),
|
Value::Int { val, .. } => val.to_string(),
|
||||||
Value::String { val, .. } => val,
|
Value::String { val, .. } => val,
|
||||||
// Explicitly propagate errors instead of dropping them.
|
// Explicitly propagate errors instead of dropping them.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
other => {
|
other => {
|
||||||
return Err(ShellError::UnsupportedInput(
|
return Err(ShellError::UnsupportedInput(
|
||||||
"Only string or list<int> ranges are supported".into(),
|
"Only string or list<int> ranges are supported".into(),
|
||||||
@ -56,7 +56,7 @@ fn parse_range(range: Value, head: Span) -> Result<(isize, isize, Span), ShellEr
|
|||||||
Value::Int { val, .. } => val.to_string(),
|
Value::Int { val, .. } => val.to_string(),
|
||||||
Value::String { val, .. } => val,
|
Value::String { val, .. } => val,
|
||||||
// Explicitly propagate errors instead of dropping them.
|
// Explicitly propagate errors instead of dropping them.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
other => {
|
other => {
|
||||||
return Err(ShellError::UnsupportedInput(
|
return Err(ShellError::UnsupportedInput(
|
||||||
"Only string or list<int> ranges are supported".into(),
|
"Only string or list<int> ranges are supported".into(),
|
||||||
@ -84,7 +84,7 @@ fn parse_range(range: Value, head: Span) -> Result<(isize, isize, Span), ShellEr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Explicitly propagate errors instead of dropping them.
|
// Explicitly propagate errors instead of dropping them.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
other => {
|
other => {
|
||||||
return Err(ShellError::UnsupportedInput(
|
return Err(ShellError::UnsupportedInput(
|
||||||
"could not perform subbytes".to_string(),
|
"could not perform subbytes".to_string(),
|
||||||
@ -249,12 +249,12 @@ fn at(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,10 +277,10 @@ fn at_impl(input: &[u8], arg: &Arguments, span: Span) -> Value {
|
|||||||
match start.cmp(&end) {
|
match start.cmp(&end) {
|
||||||
Ordering::Equal => Value::Binary { val: vec![], span },
|
Ordering::Equal => Value::Binary { val: vec![], span },
|
||||||
Ordering::Greater => Value::Error {
|
Ordering::Greater => Value::Error {
|
||||||
error: ShellError::TypeMismatch {
|
error: Box::new(ShellError::TypeMismatch {
|
||||||
err_message: "End must be greater than or equal to Start".to_string(),
|
err_message: "End must be greater than or equal to Start".to_string(),
|
||||||
span: arg.arg_span,
|
span: arg.arg_span,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
Ordering::Less => Value::Binary {
|
Ordering::Less => Value::Binary {
|
||||||
val: {
|
val: {
|
||||||
|
@ -53,7 +53,7 @@ impl Command for BytesBuild {
|
|||||||
match val {
|
match val {
|
||||||
Value::Binary { mut val, .. } => output.append(&mut val),
|
Value::Binary { mut val, .. } => output.append(&mut val),
|
||||||
// Explicitly propagate errors instead of dropping them.
|
// Explicitly propagate errors instead of dropping them.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
other => {
|
other => {
|
||||||
return Err(ShellError::TypeMismatch {
|
return Err(ShellError::TypeMismatch {
|
||||||
err_message: "only binary data arguments are supported".to_string(),
|
err_message: "only binary data arguments are supported".to_string(),
|
||||||
|
@ -55,7 +55,7 @@ impl Command for BytesCollect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Explicitly propagate errors instead of dropping them.
|
// Explicitly propagate errors instead of dropping them.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
other => {
|
other => {
|
||||||
return Err(ShellError::OnlySupportsThisInputType {
|
return Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
|
@ -93,12 +93,12 @@ fn ends_with(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,12 +135,12 @@ fn index_of(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,12 +74,12 @@ fn length(val: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,12 +142,12 @@ fn remove(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,12 +133,12 @@ fn replace(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,12 +84,12 @@ fn reverse(val: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,12 +80,12 @@ impl Command for BytesStartsWith {
|
|||||||
// Unsupported data
|
// Unsupported data
|
||||||
Ok(other) => {
|
Ok(other) => {
|
||||||
return Ok(Value::Error {
|
return Ok(Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string and binary".into(),
|
exp_input_type: "string and binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
.into_pipeline_data());
|
.into_pipeline_data());
|
||||||
}
|
}
|
||||||
@ -149,12 +149,12 @@ fn starts_with(val: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => val.clone(),
|
Value::Error { .. } => val.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ impl HashableValue {
|
|||||||
Value::Binary { val, span } => Ok(HashableValue::Binary { val, span }),
|
Value::Binary { val, span } => Ok(HashableValue::Binary { val, span }),
|
||||||
|
|
||||||
// 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(),
|
"input value is not hashable".into(),
|
||||||
format!("input type: {:?}", value.get_type()),
|
format!("input type: {:?}", value.get_type()),
|
||||||
@ -236,7 +236,7 @@ mod test {
|
|||||||
},
|
},
|
||||||
Value::Nothing { span },
|
Value::Nothing { span },
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::DidYouMean("what?".to_string(), span),
|
error: Box::new(ShellError::DidYouMean("what?".to_string(), span)),
|
||||||
},
|
},
|
||||||
Value::CellPath {
|
Value::CellPath {
|
||||||
val: CellPath {
|
val: CellPath {
|
||||||
|
@ -160,7 +160,7 @@ fn run_histogram(
|
|||||||
for v in values {
|
for v in values {
|
||||||
match v {
|
match v {
|
||||||
// Propagate existing errors.
|
// Propagate existing errors.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
_ => {
|
_ => {
|
||||||
let t = v.get_type();
|
let t = v.get_type();
|
||||||
let span = v.expect_span();
|
let span = v.expect_span();
|
||||||
@ -198,7 +198,7 @@ fn run_histogram(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Propagate existing errors.
|
// Propagate existing errors.
|
||||||
Value::Error { error } => return Err(error),
|
Value::Error { error } => return Err(*error),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,12 +193,12 @@ fn action(input: &Value, args: &Arguments, span: 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "int, filesize, float, string".into(),
|
exp_input_type: "int, filesize, float, string".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,12 +87,12 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, span: 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer or filesize".into(),
|
exp_input_type: "integer or filesize".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,13 +188,13 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer, float, filesize, string, date, duration, binary or bool"
|
exp_input_type: "integer, float, filesize, string, date, duration, binary or bool"
|
||||||
.into(),
|
.into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,17 +161,19 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
|
|||||||
},
|
},
|
||||||
Value::String { val, .. } => match string_to_boolean(val, span) {
|
Value::String { val, .. } => match string_to_boolean(val, span) {
|
||||||
Ok(val) => Value::Bool { val, span },
|
Ok(val) => Value::Bool { val, span },
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "bool, integer, float or string".into(),
|
exp_input_type: "bool, integer, float or string".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,12 +209,12 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value {
|
|||||||
Value::Error { .. } => return input.clone(),
|
Value::Error { .. } => return input.clone(),
|
||||||
other => {
|
other => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string and integer".into(),
|
exp_input_type: "string and integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -245,21 +245,21 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value {
|
|||||||
Zone::East(i) => match FixedOffset::east_opt((*i as i32) * HOUR) {
|
Zone::East(i) => match FixedOffset::east_opt((*i as i32) * HOUR) {
|
||||||
Some(eastoffset) => match_datetime!(eastoffset.timestamp_nanos(ts)),
|
Some(eastoffset) => match_datetime!(eastoffset.timestamp_nanos(ts)),
|
||||||
None => Value::Error {
|
None => Value::Error {
|
||||||
error: ShellError::DatetimeParseError(input.debug_value(), *span),
|
error: Box::new(ShellError::DatetimeParseError(input.debug_value(), *span)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Zone::West(i) => match FixedOffset::west_opt((*i as i32) * HOUR) {
|
Zone::West(i) => match FixedOffset::west_opt((*i as i32) * HOUR) {
|
||||||
Some(westoffset) => match_datetime!(westoffset.timestamp_nanos(ts)),
|
Some(westoffset) => match_datetime!(westoffset.timestamp_nanos(ts)),
|
||||||
None => Value::Error {
|
None => Value::Error {
|
||||||
error: ShellError::DatetimeParseError(input.debug_value(), *span),
|
error: Box::new(ShellError::DatetimeParseError(input.debug_value(), *span)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Zone::Error => Value::Error {
|
Zone::Error => Value::Error {
|
||||||
// This is an argument error, not an input error
|
// This is an argument error, not an input error
|
||||||
error: ShellError::TypeMismatch {
|
error: Box::new(ShellError::TypeMismatch {
|
||||||
err_message: "Invalid timezone or offset".to_string(),
|
err_message: "Invalid timezone or offset".to_string(),
|
||||||
span: *span,
|
span: *span,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -273,7 +273,7 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value {
|
|||||||
Ok(d) => Value::Date { val: d, span: head },
|
Ok(d) => Value::Date { val: d, span: head },
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
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()) },
|
error: Box::new(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()) }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -292,12 +292,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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string".into(),
|
exp_input_type: "string".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,7 +374,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn takes_timestamp_offset_as_int() {
|
fn takes_timestamp_offset_as_int() {
|
||||||
let date_int = Value::test_int(1614434140_000000000);
|
let date_int = Value::test_int(1_614_434_140_000_000_000);
|
||||||
let timezone_option = Some(Spanned {
|
let timezone_option = Some(Spanned {
|
||||||
item: Zone::East(8),
|
item: Zone::East(8),
|
||||||
span: Span::test_data(),
|
span: Span::test_data(),
|
||||||
|
@ -88,12 +88,12 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, head: Span) -> Value {
|
|||||||
match other.parse::<f64>() {
|
match other.parse::<f64>() {
|
||||||
Ok(x) => Value::float(x, head),
|
Ok(x) => Value::float(x, head),
|
||||||
Err(reason) => Value::Error {
|
Err(reason) => Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "float".to_string(),
|
to_type: "float".to_string(),
|
||||||
from_type: reason.to_string(),
|
from_type: reason.to_string(),
|
||||||
span: *span,
|
span: *span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,12 +108,12 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string, integer or bool".into(),
|
exp_input_type: "string, integer or bool".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,9 @@ fn into_duration(
|
|||||||
Box::new(move |old| action(old, &d, float_precision, head)),
|
Box::new(move |old| action(old, &d, float_precision, head)),
|
||||||
);
|
);
|
||||||
if let Err(error) = r {
|
if let Err(error) = r {
|
||||||
return Value::Error { error };
|
return Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +432,7 @@ fn action(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => Value::Error { error: e },
|
Err(e) => Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
input.clone()
|
input.clone()
|
||||||
@ -464,34 +466,36 @@ fn action(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => Value::Error { error: e },
|
Err(e) => Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "string".into(),
|
to_type: "string".into(),
|
||||||
from_type: "duration".into(),
|
from_type: "duration".into(),
|
||||||
span,
|
span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match string_to_duration(val, span, *value_span) {
|
match string_to_duration(val, span, *value_span) {
|
||||||
Ok(val) => Value::Duration { val, span },
|
Ok(val) => Value::Duration { val, span },
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string or duration".into(),
|
exp_input_type: "string or duration".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,19 +110,21 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
|
|||||||
val,
|
val,
|
||||||
span: value_span,
|
span: value_span,
|
||||||
},
|
},
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Value::Nothing { .. } => Value::Filesize {
|
Value::Nothing { .. } => Value::Filesize {
|
||||||
val: 0,
|
val: 0,
|
||||||
span: value_span,
|
span: value_span,
|
||||||
},
|
},
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string and integer".into(),
|
exp_input_type: "string and integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: value_span,
|
src_span: value_span,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -189,12 +189,12 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
_ => {
|
_ => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "float".to_string(),
|
to_type: "float".to_string(),
|
||||||
from_type: "integer".to_string(),
|
from_type: "integer".to_string(),
|
||||||
span,
|
span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +206,9 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
if radix == 10 {
|
if radix == 10 {
|
||||||
match int_from_string(val, span) {
|
match int_from_string(val, span) {
|
||||||
Ok(val) => Value::Int { val, span },
|
Ok(val) => Value::Int { val, span },
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
convert_int(input, span, radix)
|
convert_int(input, span, radix)
|
||||||
@ -232,10 +234,10 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::IncorrectValue {
|
error: Box::new(ShellError::IncorrectValue {
|
||||||
msg: "DateTime out of range for timestamp: 1677-09-21T00:12:43Z to 2262-04-11T23:47:16".to_string(),
|
msg: "DateTime out of range for timestamp: 1677-09-21T00:12:43Z to 2262-04-11T23:47:16".to_string(),
|
||||||
span
|
span
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Value::Int {
|
Value::Int {
|
||||||
@ -269,13 +271,13 @@ fn action(input: &Value, args: &Arguments, span: 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 {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "integer, float, filesize, date, string, binary, duration or bool"
|
exp_input_type: "integer, float, filesize, date, string, binary, duration or bool"
|
||||||
.into(),
|
.into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,7 +294,7 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value {
|
|||||||
{
|
{
|
||||||
match int_from_string(val, head) {
|
match int_from_string(val, head) {
|
||||||
Ok(x) => return Value::int(x, head),
|
Ok(x) => return Value::int(x, head),
|
||||||
Err(e) => return Value::Error { error: e },
|
Err(e) => return Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
} else if val.starts_with("00") {
|
} else if val.starts_with("00") {
|
||||||
// It's a padded string
|
// It's a padded string
|
||||||
@ -300,12 +302,12 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value {
|
|||||||
Ok(n) => return Value::int(n, head),
|
Ok(n) => return Value::int(n, head),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "string".to_string(),
|
to_type: "string".to_string(),
|
||||||
from_type: "int".to_string(),
|
from_type: "int".to_string(),
|
||||||
span: head,
|
span: head,
|
||||||
help: Some(e.to_string()),
|
help: Some(e.to_string()),
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,24 +318,24 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value {
|
|||||||
Value::Error { .. } => return input.clone(),
|
Value::Error { .. } => return input.clone(),
|
||||||
other => {
|
other => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string and integer".into(),
|
exp_input_type: "string and integer".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match i64::from_str_radix(i.trim(), radix) {
|
match i64::from_str_radix(i.trim(), radix) {
|
||||||
Ok(n) => Value::int(n, head),
|
Ok(n) => Value::int(n, head),
|
||||||
Err(_reason) => Value::Error {
|
Err(_reason) => Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "string".to_string(),
|
to_type: "string".to_string(),
|
||||||
from_type: "int".to_string(),
|
from_type: "int".to_string(),
|
||||||
span: head,
|
span: head,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,9 +485,9 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case("2262-04-11T23:47:16+00:00", 0x7fffffff_ffffffff)]
|
#[case("2262-04-11T23:47:16+00:00", 0x7fff_ffff_ffff_ffff)]
|
||||||
#[case("1970-01-01T00:00:00+00:00", 0)]
|
#[case("1970-01-01T00:00:00+00:00", 0)]
|
||||||
#[case("1677-09-21T00:12:44+00:00", -0x7fffffff_ffffffff)]
|
#[case("1677-09-21T00:12:44+00:00", -0x7fff_ffff_ffff_ffff)]
|
||||||
fn datetime_to_int_values_that_work(
|
fn datetime_to_int_values_that_work(
|
||||||
#[case] dt_in: DateTime<FixedOffset>,
|
#[case] dt_in: DateTime<FixedOffset>,
|
||||||
#[case] int_expected: i64,
|
#[case] int_expected: i64,
|
||||||
@ -522,14 +524,15 @@ mod test {
|
|||||||
},
|
},
|
||||||
Span::test_data(),
|
Span::test_data(),
|
||||||
);
|
);
|
||||||
if let Value::Error {
|
if let Value::Error { error } = actual {
|
||||||
error: ShellError::IncorrectValue { msg: e, .. },
|
if let ShellError::IncorrectValue { msg: e, .. } = *error {
|
||||||
} = actual
|
assert!(
|
||||||
{
|
e.contains(err_expected),
|
||||||
assert!(
|
"{e:?} doesn't contain {err_expected}"
|
||||||
e.contains(err_expected),
|
);
|
||||||
"{e:?} doesn't contain {err_expected}"
|
} else {
|
||||||
);
|
panic!("Unexpected error variant {error:?}")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("Unexpected actual value {actual:?}")
|
panic!("Unexpected actual value {actual:?}")
|
||||||
}
|
}
|
||||||
|
@ -185,12 +185,12 @@ fn into_record(
|
|||||||
Value::Record { cols, vals, span } => Value::Record { cols, vals, span },
|
Value::Record { cols, vals, span } => Value::Record { cols, vals, span },
|
||||||
Value::Error { .. } => input,
|
Value::Error { .. } => input,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string".into(),
|
exp_input_type: "string".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: call.head,
|
dst_span: call.head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Ok(res.into_pipeline_data())
|
Ok(res.into_pipeline_data())
|
||||||
|
@ -247,28 +247,28 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
span: _,
|
span: _,
|
||||||
} => Value::Error {
|
} => Value::Error {
|
||||||
// Watch out for CantConvert's argument order
|
// Watch out for CantConvert's argument order
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "string".into(),
|
to_type: "string".into(),
|
||||||
from_type: "record".into(),
|
from_type: "record".into(),
|
||||||
span,
|
span,
|
||||||
help: Some("try using the `to nuon` command".into()),
|
help: Some("try using the `to nuon` command".into()),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
Value::Binary { .. } => Value::Error {
|
Value::Binary { .. } => Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "string".into(),
|
to_type: "string".into(),
|
||||||
from_type: "binary".into(),
|
from_type: "binary".into(),
|
||||||
span,
|
span,
|
||||||
help: Some("try using the `decode` command".into()),
|
help: Some("try using the `decode` command".into()),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
x => Value::Error {
|
x => Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: String::from("string"),
|
to_type: String::from("string"),
|
||||||
from_type: x.get_type().to_string(),
|
from_type: x.get_type().to_string(),
|
||||||
span,
|
span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ fn action(
|
|||||||
Ok(Value::Nothing { span: *span })
|
Ok(Value::Nothing { span: *span })
|
||||||
}
|
}
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error } => Err(error.clone()),
|
Value::Error { error } => Err(*error.clone()),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list".into(),
|
exp_input_type: "list".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
|
@ -463,7 +463,7 @@ pub fn convert_sqlite_value_to_nu_value(value: ValueRef, span: Span) -> Value {
|
|||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::NonUtf8(span),
|
error: Box::new(ShellError::NonUtf8(span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -461,13 +461,13 @@ pub fn create_column(
|
|||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"The given local datetime representation is invalid."
|
"The given local datetime representation is invalid."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
format!("timestamp is {a:?}"),
|
format!("timestamp is {a:?}"),
|
||||||
span,
|
span,
|
||||||
Span::unknown(),
|
Span::unknown(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -476,13 +476,13 @@ pub fn create_column(
|
|||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"The given local datetime representation is invalid."
|
"The given local datetime representation is invalid."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
format!("timestamp is {a:?}"),
|
format!("timestamp is {a:?}"),
|
||||||
span,
|
span,
|
||||||
Span::unknown(),
|
Span::unknown(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -526,13 +526,13 @@ pub fn create_column(
|
|||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"The given local datetime representation is invalid."
|
"The given local datetime representation is invalid."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
format!("timestamp is {a:?}"),
|
format!("timestamp is {a:?}"),
|
||||||
span,
|
span,
|
||||||
Span::unknown(),
|
Span::unknown(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -541,13 +541,13 @@ pub fn create_column(
|
|||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"The given local datetime representation is invalid."
|
"The given local datetime representation is invalid."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
format!("timestamp is {a:?}"),
|
format!("timestamp is {a:?}"),
|
||||||
span,
|
span,
|
||||||
Span::unknown(),
|
Span::unknown(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -132,10 +132,10 @@ where
|
|||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::TypeMismatch {
|
error: Box::new(ShellError::TypeMismatch {
|
||||||
err_message: "invalid format".to_string(),
|
err_message: "invalid format".to_string(),
|
||||||
span,
|
span,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +152,10 @@ fn format_helper(value: Value, formatter: &str, formatter_span: Span, head_span:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: ShellError::DatetimeParseError(value.debug_value(), head_span),
|
error: Box::new(ShellError::DatetimeParseError(
|
||||||
|
value.debug_value(),
|
||||||
|
head_span,
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +180,7 @@ fn format_helper_rfc2822(value: Value, span: Span) -> Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: ShellError::DatetimeParseError(value.debug_value(), span),
|
error: Box::new(ShellError::DatetimeParseError(value.debug_value(), span)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ fn helper(value: Value, head: Span) -> Value {
|
|||||||
span: head,
|
span: head,
|
||||||
},
|
},
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: ShellError::DatetimeParseError(value.debug_value(), head),
|
error: Box::new(ShellError::DatetimeParseError(value.debug_value(), head)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ fn helper(val: Value, head: Span) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Date { val, span: _ } => parse_date_into_table(Ok(val), head),
|
Value::Date { val, span: _ } => parse_date_into_table(Ok(val), head),
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: DatetimeParseError(val.debug_value(), head),
|
error: Box::new(DatetimeParseError(val.debug_value(), head)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ fn helper(val: Value, head: Span) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Date { val, span: _ } => parse_date_into_table(Ok(val), head),
|
Value::Date { val, span: _ } => parse_date_into_table(Ok(val), head),
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: DatetimeParseError(val.debug_value(), head),
|
error: Box::new(DatetimeParseError(val.debug_value(), head)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ fn helper(value: Value, head: Span, timezone: &Spanned<String>) -> Value {
|
|||||||
_to_timezone(dt.with_timezone(dt.offset()), timezone, head)
|
_to_timezone(dt.with_timezone(dt.offset()), timezone, head)
|
||||||
}
|
}
|
||||||
_ => Value::Error {
|
_ => Value::Error {
|
||||||
error: ShellError::DatetimeParseError(value.debug_value(), head),
|
error: Box::new(ShellError::DatetimeParseError(value.debug_value(), head)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,10 +137,10 @@ fn _to_timezone(dt: DateTime<FixedOffset>, timezone: &Spanned<String>, span: Spa
|
|||||||
match datetime_in_timezone(&dt, timezone.item.as_str()) {
|
match datetime_in_timezone(&dt, timezone.item.as_str()) {
|
||||||
Ok(dt) => Value::Date { val: dt, span },
|
Ok(dt) => Value::Date { val: dt, span },
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::TypeMismatch {
|
error: Box::new(ShellError::TypeMismatch {
|
||||||
err_message: String::from("invalid time zone"),
|
err_message: String::from("invalid time zone"),
|
||||||
span: timezone.span,
|
span: timezone.span,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ pub(crate) fn parse_date_from_string(
|
|||||||
LocalResult::Single(d) => Ok(d),
|
LocalResult::Single(d) => Ok(d),
|
||||||
LocalResult::Ambiguous(d, _) => Ok(d),
|
LocalResult::Ambiguous(d, _) => Ok(d),
|
||||||
LocalResult::None => Err(Value::Error {
|
LocalResult::None => Err(Value::Error {
|
||||||
error: ShellError::DatetimeParseError(input.to_string(), span),
|
error: Box::new(ShellError::DatetimeParseError(input.to_string(), span)),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => Err(Value::Error {
|
Err(_) => Err(Value::Error {
|
||||||
error: ShellError::DatetimeParseError(input.to_string(), span),
|
error: Box::new(ShellError::DatetimeParseError(input.to_string(), span)),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,9 @@ fn get_expression_as_value(
|
|||||||
) -> Value {
|
) -> Value {
|
||||||
match eval_expression(engine_state, stack, inner_expr) {
|
match eval_expression(engine_state, stack, inner_expr) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,13 +379,13 @@ fn interactive_copy(
|
|||||||
);
|
);
|
||||||
if let Err(e) = interaction {
|
if let Err(e) = interaction {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
e.to_string(),
|
e.to_string(),
|
||||||
e.to_string(),
|
e.to_string(),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
} else if !confirmed {
|
} else if !confirmed {
|
||||||
let msg = format!("{:} not copied to {:}", src.display(), dst.display());
|
let msg = format!("{:} not copied to {:}", src.display(), dst.display());
|
||||||
@ -518,13 +518,13 @@ fn copy_symlink(
|
|||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
vec![],
|
vec![],
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -551,7 +551,13 @@ fn copy_symlink(
|
|||||||
Value::String { val: msg, span }
|
Value::String { val: msg, span }
|
||||||
}
|
}
|
||||||
Err(e) => Value::Error {
|
Err(e) => Value::Error {
|
||||||
error: ShellError::GenericError(e.to_string(), e.to_string(), Some(span), None, vec![]),
|
error: Box::new(ShellError::GenericError(
|
||||||
|
e.to_string(),
|
||||||
|
e.to_string(),
|
||||||
|
Some(span),
|
||||||
|
None,
|
||||||
|
vec![],
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -593,5 +599,7 @@ fn convert_io_error(error: std::io::Error, src: PathBuf, dst: PathBuf, span: Spa
|
|||||||
_ => ShellError::IOErrorSpanned(message_src, span),
|
_ => ShellError::IOErrorSpanned(message_src, span),
|
||||||
};
|
};
|
||||||
|
|
||||||
Value::Error { error: shell_error }
|
Value::Error {
|
||||||
|
error: Box::new(shell_error),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,10 +255,14 @@ impl Command for Ls {
|
|||||||
);
|
);
|
||||||
match entry {
|
match entry {
|
||||||
Ok(value) => Some(value),
|
Ok(value) => Some(value),
|
||||||
Err(err) => Some(Value::Error { error: err }),
|
Err(err) => Some(Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Some(Value::Error { error: err }),
|
Err(err) => Some(Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Some(Value::Nothing { span: call_span }),
|
_ => Some(Value::Nothing { span: call_span }),
|
||||||
|
@ -193,7 +193,9 @@ impl Command for Mv {
|
|||||||
interactive,
|
interactive,
|
||||||
);
|
);
|
||||||
if let Err(error) = result {
|
if let Err(error) = result {
|
||||||
Some(Value::Error { error })
|
Some(Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
})
|
||||||
} else if verbose {
|
} else if verbose {
|
||||||
let val = match result {
|
let val = match result {
|
||||||
Ok(true) => format!(
|
Ok(true) => format!(
|
||||||
|
@ -405,13 +405,13 @@ fn rm(
|
|||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
let msg = format!("Could not delete because: {e:}");
|
let msg = format!("Could not delete because: {e:}");
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
msg,
|
msg,
|
||||||
e.to_string(),
|
e.to_string(),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
} else if verbose {
|
} else if verbose {
|
||||||
let msg = if interactive && !confirmed {
|
let msg = if interactive && !confirmed {
|
||||||
@ -427,25 +427,25 @@ fn rm(
|
|||||||
} else {
|
} else {
|
||||||
let msg = format!("Cannot remove {:}. try --recursive", f.to_string_lossy());
|
let msg = format!("Cannot remove {:}. try --recursive", f.to_string_lossy());
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
msg,
|
msg,
|
||||||
"cannot remove non-empty directory".into(),
|
"cannot remove non-empty directory".into(),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("no such file or directory: {:}", f.to_string_lossy());
|
let msg = format!("no such file or directory: {:}", f.to_string_lossy());
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::GenericError(
|
error: Box::new(ShellError::GenericError(
|
||||||
msg,
|
msg,
|
||||||
"no such file or directory".into(),
|
"no such file or directory".into(),
|
||||||
Some(span),
|
Some(span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -250,7 +250,7 @@ fn value_to_bytes(value: Value) -> Result<Vec<u8>, ShellError> {
|
|||||||
Ok(val.into_bytes())
|
Ok(val.into_bytes())
|
||||||
}
|
}
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error } => Err(error),
|
Value::Error { error } => Err(*error),
|
||||||
other => Ok(other.as_string()?.into_bytes()),
|
other => Ok(other.as_string()?.into_bytes()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,7 +376,7 @@ fn stream_to_file(
|
|||||||
Value::String { val, .. } => val.into_bytes(),
|
Value::String { val, .. } => val.into_bytes(),
|
||||||
Value::Binary { val, .. } => val,
|
Value::Binary { val, .. } => val,
|
||||||
// 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::OnlySupportsThisInputType {
|
return Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string or binary".into(),
|
exp_input_type: "string or binary".into(),
|
||||||
|
@ -137,7 +137,7 @@ fn getcol(
|
|||||||
.into_pipeline_data(ctrlc)
|
.into_pipeline_data(ctrlc)
|
||||||
.set_metadata(metadata)),
|
.set_metadata(metadata)),
|
||||||
// Propagate errors
|
// Propagate errors
|
||||||
PipelineData::Value(Value::Error { error }, ..) => Err(error),
|
PipelineData::Value(Value::Error { error }, ..) => Err(*error),
|
||||||
PipelineData::Value(other, ..) => Err(ShellError::OnlySupportsThisInputType {
|
PipelineData::Value(other, ..) => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "record or table".into(),
|
exp_input_type: "record or table".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
|
@ -167,7 +167,9 @@ with 'transpose' first."#
|
|||||||
Err(ShellError::Break(_)) => None,
|
Err(ShellError::Break(_)) => None,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let error = chain_error_with_input(error, input_span);
|
let error = chain_error_with_input(error, input_span);
|
||||||
Some(Value::Error { error })
|
Some(Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -187,7 +189,11 @@ with 'transpose' first."#
|
|||||||
let x = match x {
|
let x = match x {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(ShellError::Break(_)) => return None,
|
Err(ShellError::Break(_)) => return None,
|
||||||
Err(err) => return Some(Value::Error { error: err }),
|
Err(err) => {
|
||||||
|
return Some(Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(var) = block.signature.get_positional(0) {
|
if let Some(var) = block.signature.get_positional(0) {
|
||||||
@ -208,7 +214,7 @@ with 'transpose' first."#
|
|||||||
Ok(v) => Some(v.into_value(span)),
|
Ok(v) => Some(v.into_value(span)),
|
||||||
Err(ShellError::Break(_)) => None,
|
Err(ShellError::Break(_)) => None,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let error = chain_error_with_input(error, input_span);
|
let error = Box::new(chain_error_with_input(error, input_span));
|
||||||
Some(Value::Error { error })
|
Some(Value::Error { error })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => Some(Value::Error {
|
Err(error) => Some(Value::Error {
|
||||||
error: chain_error_with_input(error, x.span()),
|
error: Box::new(chain_error_with_input(error, x.span())),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -118,7 +118,11 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
|
|
||||||
let x = match x {
|
let x = match x {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(err) => return Some(Value::Error { error: err }),
|
Err(err) => {
|
||||||
|
return Some(Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(var) = block.signature.get_positional(0) {
|
if let Some(var) = block.signature.get_positional(0) {
|
||||||
@ -144,7 +148,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => Some(Value::Error {
|
Err(error) => Some(Value::Error {
|
||||||
error: chain_error_with_input(error, x.span()),
|
error: Box::new(chain_error_with_input(error, x.span())),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -177,7 +181,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => Some(Value::Error {
|
Err(error) => Some(Value::Error {
|
||||||
error: chain_error_with_input(error, x.span()),
|
error: Box::new(chain_error_with_input(error, x.span())),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
.into_pipeline_data(ctrlc))
|
.into_pipeline_data(ctrlc))
|
||||||
|
@ -522,7 +522,7 @@ 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(),
|
"unsupported type from raw stream".into(),
|
||||||
|
@ -141,7 +141,7 @@ fn first_helper(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error } => Err(error),
|
Value::Error { error } => Err(*error),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list, binary or range".into(),
|
exp_input_type: "list, binary or range".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
|
@ -154,7 +154,7 @@ enum TableInside<'a> {
|
|||||||
fn flat_value(columns: &[CellPath], item: &Value, _name_tag: Span, all: bool) -> Vec<Value> {
|
fn flat_value(columns: &[CellPath], item: &Value, _name_tag: Span, all: bool) -> Vec<Value> {
|
||||||
let tag = match item.span() {
|
let tag = match item.span() {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => return vec![Value::Error { error: e }],
|
Err(e) => return vec![Value::Error { error: Box::new(e) }],
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
@ -172,19 +172,19 @@ fn flat_value(columns: &[CellPath], item: &Value, _name_tag: Span, all: bool) ->
|
|||||||
Value::Error { .. } => return vec![item.clone()],
|
Value::Error { .. } => return vec![item.clone()],
|
||||||
other => {
|
other => {
|
||||||
return vec![Value::Error {
|
return vec![Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "record".into(),
|
exp_input_type: "record".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: _name_tag,
|
dst_span: _name_tag,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let s = match item.span() {
|
let s = match item.span() {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => return vec![Value::Error { error: e }],
|
Err(e) => return vec![Value::Error { error: Box::new(e) }],
|
||||||
};
|
};
|
||||||
|
|
||||||
let records_iterator = {
|
let records_iterator = {
|
||||||
@ -229,12 +229,12 @@ fn flat_value(columns: &[CellPath], item: &Value, _name_tag: Span, all: bool) ->
|
|||||||
if all && vals.iter().all(|f| f.as_record().is_ok()) =>
|
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{ error: ShellError::UnsupportedInput(
|
return vec![Value::Error{ error: Box::new(ShellError::UnsupportedInput(
|
||||||
"can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(),
|
"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(),
|
"value originates from here".into(),
|
||||||
s,
|
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)
|
||||||
@ -267,12 +267,12 @@ fn flat_value(columns: &[CellPath], item: &Value, _name_tag: Span, all: bool) ->
|
|||||||
}
|
}
|
||||||
Value::List { vals: values, span } => {
|
Value::List { vals: values, span } => {
|
||||||
if need_flatten && inner_table.is_some() {
|
if need_flatten && inner_table.is_some() {
|
||||||
return vec![Value::Error{ error: ShellError::UnsupportedInput(
|
return vec![Value::Error{ error: Box::new(ShellError::UnsupportedInput(
|
||||||
"can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(),
|
"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(),
|
"value originates from here".into(),
|
||||||
s,
|
s,
|
||||||
*span
|
*span
|
||||||
)}
|
))}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ pub fn group(
|
|||||||
Grouper::ByColumn(Some(column_name)) => {
|
Grouper::ByColumn(Some(column_name)) => {
|
||||||
let block = Box::new(move |_, row: &Value| {
|
let block = Box::new(move |_, row: &Value| {
|
||||||
if let Value::Error { error } = row {
|
if let Value::Error { error } = row {
|
||||||
return Err(error.clone());
|
return Err(*error.clone());
|
||||||
};
|
};
|
||||||
match row.get_data_by_key(&column_name.item) {
|
match row.get_data_by_key(&column_name.item) {
|
||||||
Some(group_key) => Ok(group_key.as_string()?),
|
Some(group_key) => Ok(group_key.as_string()?),
|
||||||
|
@ -163,12 +163,12 @@ fn insert(
|
|||||||
pd.into_value(span),
|
pd.into_value(span),
|
||||||
span,
|
span,
|
||||||
) {
|
) {
|
||||||
return Value::Error { error: e };
|
return Value::Error { error: Box::new(e) };
|
||||||
}
|
}
|
||||||
|
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
Err(e) => Value::Error { error: e },
|
Err(e) => Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ctrlc,
|
ctrlc,
|
||||||
@ -199,7 +199,7 @@ fn insert(
|
|||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
input.insert_data_at_cell_path(&cell_path.members, replacement, span)
|
input.insert_data_at_cell_path(&cell_path.members, replacement, span)
|
||||||
{
|
{
|
||||||
return Value::Error { error: e };
|
return Value::Error { error: Box::new(e) };
|
||||||
}
|
}
|
||||||
|
|
||||||
input
|
input
|
||||||
|
@ -86,7 +86,7 @@ fn length_row(call: &Call, input: PipelineData) -> Result<PipelineData, ShellErr
|
|||||||
// Check for and propagate errors
|
// Check for and propagate errors
|
||||||
for value in input.into_iter() {
|
for value in input.into_iter() {
|
||||||
if let Value::Error { error } = value {
|
if let Value::Error { error } = value {
|
||||||
return Err(error);
|
return Err(*error);
|
||||||
}
|
}
|
||||||
count += 1
|
count += 1
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ impl Command for Lines {
|
|||||||
PipelineData::Value(val, ..) => {
|
PipelineData::Value(val, ..) => {
|
||||||
match val {
|
match val {
|
||||||
// Propagate existing errors
|
// Propagate existing errors
|
||||||
Value::Error { error } => Err(error),
|
Value::Error { error } => Err(*error),
|
||||||
_ => Err(ShellError::OnlySupportsThisInputType {
|
_ => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string or raw data".into(),
|
exp_input_type: "string or raw data".into(),
|
||||||
wrong_type: val.get_type().to_string(),
|
wrong_type: val.get_type().to_string(),
|
||||||
@ -129,7 +129,9 @@ impl Command for Lines {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move |(_idx, x)| match x {
|
.map(move |(_idx, x)| match x {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(err) => Value::Error { error: err },
|
Err(err) => Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.into_pipeline_data(ctrlc)),
|
.into_pipeline_data(ctrlc)),
|
||||||
}
|
}
|
||||||
@ -232,7 +234,7 @@ impl Iterator for RawStreamLinesAdapter {
|
|||||||
self.queue.append(&mut lines);
|
self.queue.append(&mut lines);
|
||||||
}
|
}
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error } => return Some(Err(error)),
|
Value::Error { error } => return Some(Err(*error)),
|
||||||
other => {
|
other => {
|
||||||
return Some(Err(ShellError::OnlySupportsThisInputType {
|
return Some(Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string".into(),
|
exp_input_type: "string".into(),
|
||||||
|
@ -125,11 +125,15 @@ repeating this process with row 1, and so on."#
|
|||||||
span: call.head,
|
span: call.head,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(_, None) => inp,
|
(_, None) => inp,
|
||||||
(Err(error), _) => Value::Error { error },
|
(Err(error), _) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
if let Some(md) = metadata {
|
||||||
|
@ -158,9 +158,13 @@ impl Command for Move {
|
|||||||
call.head,
|
call.head,
|
||||||
) {
|
) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
},
|
},
|
||||||
Err(error) => Value::Error { error },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
if let Some(md) = metadata {
|
||||||
|
@ -121,7 +121,7 @@ impl Command for ParEach {
|
|||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(error) => Value::Error {
|
Err(error) => Value::Error {
|
||||||
error: chain_error_with_input(error, val_span),
|
error: Box::new(chain_error_with_input(error, val_span)),
|
||||||
}
|
}
|
||||||
.into_pipeline_data(),
|
.into_pipeline_data(),
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ impl Command for ParEach {
|
|||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(error) => Value::Error {
|
Err(error) => Value::Error {
|
||||||
error: chain_error_with_input(error, val_span),
|
error: Box::new(chain_error_with_input(error, val_span)),
|
||||||
}
|
}
|
||||||
.into_pipeline_data(),
|
.into_pipeline_data(),
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ impl Command for ParEach {
|
|||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(error) => Value::Error {
|
Err(error) => Value::Error {
|
||||||
error: chain_error_with_input(error, val_span),
|
error: Box::new(chain_error_with_input(error, val_span)),
|
||||||
}
|
}
|
||||||
.into_pipeline_data(),
|
.into_pipeline_data(),
|
||||||
}
|
}
|
||||||
@ -206,7 +206,12 @@ impl Command for ParEach {
|
|||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
let x = match x {
|
let x = match x {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(err) => return Value::Error { error: err }.into_pipeline_data(),
|
Err(err) => {
|
||||||
|
return Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
}
|
||||||
|
.into_pipeline_data()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let block = engine_state.get_block(block_id);
|
let block = engine_state.get_block(block_id);
|
||||||
@ -228,7 +233,10 @@ impl Command for ParEach {
|
|||||||
redirect_stderr,
|
redirect_stderr,
|
||||||
) {
|
) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
Err(error) => Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
}
|
||||||
|
.into_pipeline_data(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
@ -141,7 +141,7 @@ fn rename(
|
|||||||
// check if the specified column to be renamed exists
|
// check if the specified column to be renamed exists
|
||||||
if !cols.contains(&c[0]) {
|
if !cols.contains(&c[0]) {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
format!(
|
format!(
|
||||||
"The column '{}' does not exist in the input",
|
"The column '{}' does not exist in the input",
|
||||||
&c[0]
|
&c[0]
|
||||||
@ -151,7 +151,7 @@ fn rename(
|
|||||||
specified_col_span.unwrap_or(head_span),
|
specified_col_span.unwrap_or(head_span),
|
||||||
// Arrow 2 points at the input value.
|
// Arrow 2 points at the input value.
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for (idx, val) in cols.iter_mut().enumerate() {
|
for (idx, val) in cols.iter_mut().enumerate() {
|
||||||
@ -177,12 +177,12 @@ fn rename(
|
|||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { .. } => item.clone(),
|
Value::Error { .. } => item.clone(),
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "record".into(),
|
exp_input_type: "record".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head_span,
|
dst_span: head_span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
engine_state.ctrlc.clone(),
|
engine_state.ctrlc.clone(),
|
||||||
|
@ -73,7 +73,7 @@ impl Command for Take {
|
|||||||
.into_pipeline_data(ctrlc)
|
.into_pipeline_data(ctrlc)
|
||||||
.set_metadata(metadata)),
|
.set_metadata(metadata)),
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error } => Err(error),
|
Value::Error { error } => Err(*error),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list, binary or range".into(),
|
exp_input_type: "list, binary or range".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
|
@ -132,12 +132,12 @@ fn update(
|
|||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
input.update_data_at_cell_path(&cell_path.members, pd.into_value(span))
|
input.update_data_at_cell_path(&cell_path.members, pd.into_value(span))
|
||||||
{
|
{
|
||||||
return Value::Error { error: e };
|
return Value::Error { error: Box::new(e) };
|
||||||
}
|
}
|
||||||
|
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
Err(e) => Value::Error { error: e },
|
Err(e) => Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ctrlc,
|
ctrlc,
|
||||||
@ -174,7 +174,7 @@ fn update(
|
|||||||
let replacement = replacement.clone();
|
let replacement = replacement.clone();
|
||||||
|
|
||||||
if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement) {
|
if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement) {
|
||||||
return Value::Error { error: e };
|
return Value::Error { error: Box::new(e) };
|
||||||
}
|
}
|
||||||
|
|
||||||
input
|
input
|
||||||
|
@ -253,7 +253,7 @@ fn process_cell(
|
|||||||
redirect_stderr,
|
redirect_stderr,
|
||||||
) {
|
) {
|
||||||
Ok(pd) => pd.into_value(span),
|
Ok(pd) => pd.into_value(span),
|
||||||
Err(e) => Value::Error { error: e },
|
Err(e) => Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,12 +154,12 @@ fn upsert(
|
|||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
input.upsert_data_at_cell_path(&cell_path.members, pd.into_value(span))
|
input.upsert_data_at_cell_path(&cell_path.members, pd.into_value(span))
|
||||||
{
|
{
|
||||||
return Value::Error { error: e };
|
return Value::Error { error: Box::new(e) };
|
||||||
}
|
}
|
||||||
|
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
Err(e) => Value::Error { error: e },
|
Err(e) => Value::Error { error: Box::new(e) },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ctrlc,
|
ctrlc,
|
||||||
@ -195,7 +195,7 @@ fn upsert(
|
|||||||
let replacement = replacement.clone();
|
let replacement = replacement.clone();
|
||||||
|
|
||||||
if let Err(e) = input.upsert_data_at_cell_path(&cell_path.members, replacement) {
|
if let Err(e) = input.upsert_data_at_cell_path(&cell_path.members, replacement) {
|
||||||
return Value::Error { error: e };
|
return Value::Error { error: Box::new(e) };
|
||||||
}
|
}
|
||||||
|
|
||||||
input
|
input
|
||||||
|
@ -119,7 +119,7 @@ pub fn get_values<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error { error } => return Err(error.clone()),
|
Value::Error { error } => return Err(*error.clone()),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ShellError::OnlySupportsThisInputType {
|
return Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "record or table".into(),
|
exp_input_type: "record or table".into(),
|
||||||
@ -176,7 +176,7 @@ fn values(
|
|||||||
Ok(vals.into_pipeline_data(ctrlc).set_metadata(metadata))
|
Ok(vals.into_pipeline_data(ctrlc).set_metadata(metadata))
|
||||||
}
|
}
|
||||||
// Propagate errors
|
// Propagate errors
|
||||||
PipelineData::Value(Value::Error { error }, ..) => Err(error),
|
PipelineData::Value(Value::Error { error }, ..) => Err(*error),
|
||||||
PipelineData::Value(other, ..) => Err(ShellError::OnlySupportsThisInputType {
|
PipelineData::Value(other, ..) => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "record or table".into(),
|
exp_input_type: "record or table".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
|
@ -97,7 +97,9 @@ not supported."#
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Some(Value::Error { error: err }),
|
Err(err) => Some(Value::Error {
|
||||||
|
error: Box::new(err),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(ctrlc)
|
.into_pipeline_data(ctrlc)
|
||||||
|
@ -77,7 +77,9 @@ impl Command for FromJson {
|
|||||||
} else {
|
} else {
|
||||||
match convert_string_to_value(x.to_string(), span) {
|
match convert_string_to_value(x.to_string(), span) {
|
||||||
Ok(v) => Some(v),
|
Ok(v) => Some(v),
|
||||||
Err(error) => Some(Value::Error { error }),
|
Err(error) => Some(Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -119,12 +121,12 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value {
|
|||||||
nu_json::Value::U64(u) => {
|
nu_json::Value::U64(u) => {
|
||||||
if *u > i64::MAX as u64 {
|
if *u > i64::MAX as u64 {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "i64 sized integer".into(),
|
to_type: "i64 sized integer".into(),
|
||||||
from_type: "value larger than i64".into(),
|
from_type: "value larger than i64".into(),
|
||||||
span,
|
span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Value::Int {
|
Value::Int {
|
||||||
|
@ -93,7 +93,7 @@ fn collect_binary(input: PipelineData, span: Span) -> Result<Vec<u8>, ShellError
|
|||||||
Some(Value::Binary { val: b, .. }) => {
|
Some(Value::Binary { val: b, .. }) => {
|
||||||
bytes.extend_from_slice(&b);
|
bytes.extend_from_slice(&b);
|
||||||
}
|
}
|
||||||
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(),
|
"Expected binary from pipeline".to_string(),
|
||||||
|
@ -16,7 +16,7 @@ fn from_value_to_delimited_string(
|
|||||||
}
|
}
|
||||||
Value::List { vals, span } => table_to_delimited(vals, span, separator, config, head),
|
Value::List { vals, span } => table_to_delimited(vals, span, separator, config, head),
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error } => Err(error.clone()),
|
Value::Error { error } => Err(*error.clone()),
|
||||||
v => Err(make_unsupported_input_error(v, head, v.expect_span())),
|
v => Err(make_unsupported_input_error(v, head, v.expect_span())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ fn to_string_tagged_value(
|
|||||||
Value::Date { val, .. } => Ok(val.to_string()),
|
Value::Date { val, .. } => Ok(val.to_string()),
|
||||||
Value::Nothing { .. } => Ok(String::new()),
|
Value::Nothing { .. } => Ok(String::new()),
|
||||||
// Propagate existing errors
|
// Propagate existing errors
|
||||||
Value::Error { error } => Err(error.clone()),
|
Value::Error { error } => Err(*error.clone()),
|
||||||
_ => Err(make_unsupported_input_error(v, head, span)),
|
_ => Err(make_unsupported_input_error(v, head, span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,12 @@ impl Command for ToJson {
|
|||||||
}
|
}
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data()),
|
||||||
_ => Ok(Value::Error {
|
_ => Ok(Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "JSON".into(),
|
to_type: "JSON".into(),
|
||||||
from_type: value.get_type().to_string(),
|
from_type: value.get_type().to_string(),
|
||||||
span,
|
span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data()),
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ pub fn value_to_json_value(v: &Value) -> Result<nu_json::Value, ShellError> {
|
|||||||
),
|
),
|
||||||
|
|
||||||
Value::List { vals, .. } => nu_json::Value::Array(json_list(vals)?),
|
Value::List { vals, .. } => nu_json::Value::Array(json_list(vals)?),
|
||||||
Value::Error { error } => return Err(error.clone()),
|
Value::Error { error } => return Err(*error.clone()),
|
||||||
Value::Closure { .. } | Value::Block { .. } | Value::Range { .. } => nu_json::Value::Null,
|
Value::Closure { .. } | Value::Block { .. } | Value::Range { .. } => nu_json::Value::Null,
|
||||||
Value::Binary { val, .. } => {
|
Value::Binary { val, .. } => {
|
||||||
nu_json::Value::Array(val.iter().map(|x| nu_json::Value::U64(*x as u64)).collect())
|
nu_json::Value::Array(val.iter().map(|x| nu_json::Value::U64(*x as u64)).collect())
|
||||||
|
@ -101,7 +101,7 @@ pub fn value_to_string(v: &Value, span: Span) -> Result<String, ShellError> {
|
|||||||
// 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)),
|
||||||
// Propagate existing errors
|
// Propagate existing errors
|
||||||
Value::Error { error } => Err(error.clone()),
|
Value::Error { error } => Err(*error.clone()),
|
||||||
// FIXME: make filesizes use the shortest lossless representation.
|
// FIXME: make filesizes use the shortest lossless representation.
|
||||||
Value::Filesize { val, .. } => Ok(format!("{}b", *val)),
|
Value::Filesize { val, .. } => Ok(format!("{}b", *val)),
|
||||||
Value::Float { val, .. } => {
|
Value::Float { val, .. } => {
|
||||||
|
@ -77,7 +77,7 @@ fn helper(engine_state: &EngineState, v: &Value) -> Result<toml::Value, ShellErr
|
|||||||
toml::Value::String(code)
|
toml::Value::String(code)
|
||||||
}
|
}
|
||||||
Value::Nothing { .. } => toml::Value::String("<Nothing>".to_string()),
|
Value::Nothing { .. } => toml::Value::String("<Nothing>".to_string()),
|
||||||
Value::Error { error } => return Err(error.clone()),
|
Value::Error { error } => return Err(*error.clone()),
|
||||||
Value::Binary { val, .. } => toml::Value::Array(
|
Value::Binary { val, .. } => toml::Value::Array(
|
||||||
val.iter()
|
val.iter()
|
||||||
.map(|x| toml::Value::Integer(*x as i64))
|
.map(|x| toml::Value::Integer(*x as i64))
|
||||||
@ -118,12 +118,12 @@ fn toml_into_pipeline_data(
|
|||||||
}
|
}
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data()),
|
||||||
_ => Ok(Value::Error {
|
_ => Ok(Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "TOML".into(),
|
to_type: "TOML".into(),
|
||||||
from_type: value_type.to_string(),
|
from_type: value_type.to_string(),
|
||||||
span,
|
span,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data()),
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ fn value_to_toml_value(
|
|||||||
match v {
|
match v {
|
||||||
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()),
|
format!("{:?} is not valid top-level TOML", v.get_type()),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
|
@ -79,7 +79,7 @@ pub fn value_to_yaml_value(v: &Value) -> Result<serde_yaml::Value, ShellError> {
|
|||||||
Value::Block { .. } => serde_yaml::Value::Null,
|
Value::Block { .. } => serde_yaml::Value::Null,
|
||||||
Value::Closure { .. } => serde_yaml::Value::Null,
|
Value::Closure { .. } => serde_yaml::Value::Null,
|
||||||
Value::Nothing { .. } => serde_yaml::Value::Null,
|
Value::Nothing { .. } => serde_yaml::Value::Null,
|
||||||
Value::Error { error } => return Err(error.clone()),
|
Value::Error { error } => return Err(*error.clone()),
|
||||||
Value::Binary { val, .. } => serde_yaml::Value::Sequence(
|
Value::Binary { val, .. } => serde_yaml::Value::Sequence(
|
||||||
val.iter()
|
val.iter()
|
||||||
.map(|x| serde_yaml::Value::Number(serde_yaml::Number::from(*x)))
|
.map(|x| serde_yaml::Value::Number(serde_yaml::Number::from(*x)))
|
||||||
@ -111,12 +111,12 @@ fn to_yaml(input: PipelineData, head: Span) -> Result<PipelineData, ShellError>
|
|||||||
}
|
}
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data()),
|
||||||
_ => Ok(Value::Error {
|
_ => Ok(Value::Error {
|
||||||
error: ShellError::CantConvert {
|
error: Box::new(ShellError::CantConvert {
|
||||||
to_type: "YAML".into(),
|
to_type: "YAML".into(),
|
||||||
from_type: value.get_type().to_string(),
|
from_type: value.get_type().to_string(),
|
||||||
span: head,
|
span: head,
|
||||||
help: None,
|
help: None,
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data()),
|
||||||
}
|
}
|
||||||
|
@ -111,16 +111,20 @@ where
|
|||||||
other => {
|
other => {
|
||||||
let span = match input.span() {
|
let span = match input.span() {
|
||||||
Ok(span) => span,
|
Ok(span) => span,
|
||||||
Err(error) => return Value::Error { error },
|
Err(error) => {
|
||||||
|
return Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "string or binary".into(),
|
exp_input_type: "string or binary".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: span,
|
dst_span: span,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -76,7 +76,9 @@ where
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if let Err(error) = r {
|
if let Err(error) = r {
|
||||||
return Value::Error { error };
|
return Value::Error {
|
||||||
|
error: Box::new(error),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v
|
v
|
||||||
|
@ -68,12 +68,12 @@ fn abs_helper(val: Value, head: Span) -> Value {
|
|||||||
},
|
},
|
||||||
Value::Error { .. } => val,
|
Value::Error { .. } => val,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,23 +77,23 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
|||||||
Value::Float { val, span }
|
Value::Float { val, span }
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"'arccos' undefined for values outside the closed interval [-1, 1].".into(),
|
"'arccos' undefined for values outside the closed interval [-1, 1].".into(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,23 +67,23 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
Value::Float { val, span }
|
Value::Float { val, span }
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"'arccosh' undefined for values below 1.".into(),
|
"'arccosh' undefined for values below 1.".into(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,23 +78,23 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
|||||||
Value::Float { val, span }
|
Value::Float { val, span }
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"'arcsin' undefined for values outside the closed interval [-1, 1].".into(),
|
"'arcsin' undefined for values outside the closed interval [-1, 1].".into(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,12 +67,12 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,12 +78,12 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,23 +67,23 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
Value::Float { val, span }
|
Value::Float { val, span }
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"'arctanh' undefined for values outside the open interval (-1, 1).".into(),
|
"'arctanh' undefined for values outside the open interval (-1, 1).".into(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,12 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
},
|
},
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,12 +88,12 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,12 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,12 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
},
|
},
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,23 +67,23 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
Value::Float { val, span }
|
Value::Float { val, span }
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"'ln' undefined for values outside the open interval (0, Inf).".into(),
|
"'ln' undefined for values outside the open interval (0, Inf).".into(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,13 +96,13 @@ fn operate(value: Value, head: Span, base: f64) -> Value {
|
|||||||
|
|
||||||
if val <= 0.0 {
|
if val <= 0.0 {
|
||||||
return Value::Error {
|
return Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
"'math log' undefined for values outside the open interval (0, Inf)."
|
"'math log' undefined for values outside the open interval (0, Inf)."
|
||||||
.into(),
|
.into(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Specialize for better precision/performance
|
// Specialize for better precision/performance
|
||||||
@ -118,12 +118,12 @@ fn operate(value: Value, head: Span, base: f64) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ pub fn mode(values: &[Value], _span: Span, head: &Span) -> Result<Value, ShellEr
|
|||||||
Value::Filesize { val, .. } => {
|
Value::Filesize { val, .. } => {
|
||||||
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(),
|
"Unable to give a result with this input".to_string(),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
|
@ -112,7 +112,7 @@ pub fn sum(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellError
|
|||||||
| Value::Duration { .. } => {
|
| Value::Duration { .. } => {
|
||||||
acc = acc.add(head, value, head)?;
|
acc = acc.add(head, value, head)?;
|
||||||
}
|
}
|
||||||
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(),
|
"Attempted to compute the sum of a value that cannot be summed".to_string(),
|
||||||
@ -145,7 +145,7 @@ pub fn product(data: Vec<Value>, span: Span, head: Span) -> Result<Value, ShellE
|
|||||||
Value::Int { .. } | Value::Float { .. } => {
|
Value::Int { .. } | Value::Float { .. } => {
|
||||||
acc = acc.mul(head, value, head)?;
|
acc = acc.mul(head, value, head)?;
|
||||||
}
|
}
|
||||||
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"
|
"Attempted to compute the product of a value that cannot be multiplied"
|
||||||
|
@ -95,12 +95,12 @@ fn operate(value: Value, head: Span, precision: Option<i64>) -> Value {
|
|||||||
Value::Int { .. } => value,
|
Value::Int { .. } => value,
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,12 +88,12 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,12 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,24 +73,24 @@ fn operate(value: Value, head: Span) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_negative_sqrt(head: Span, span: Span) -> Value {
|
fn error_negative_sqrt(head: Span, span: Span) -> Value {
|
||||||
Value::Error {
|
Value::Error {
|
||||||
error: ShellError::UnsupportedInput(
|
error: Box::new(ShellError::UnsupportedInput(
|
||||||
String::from("Can't square root a negative number"),
|
String::from("Can't square root a negative number"),
|
||||||
"value originates from here".into(),
|
"value originates from here".into(),
|
||||||
head,
|
head,
|
||||||
span,
|
span,
|
||||||
),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,12 +86,12 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
|||||||
}
|
}
|
||||||
Value::Error { .. } => value,
|
Value::Error { .. } => value,
|
||||||
other => Value::Error {
|
other => Value::Error {
|
||||||
error: ShellError::OnlySupportsThisInputType {
|
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "numeric".into(),
|
exp_input_type: "numeric".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: head,
|
dst_span: head,
|
||||||
src_span: other.expect_span(),
|
src_span: other.expect_span(),
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user