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