CantConvert improvements (#4926)

* CantConvert improvements

* cargo fmt
This commit is contained in:
Jonathan Moore 2022-03-24 07:04:31 -05:00 committed by GitHub
parent 5d5b02d8dc
commit ea7c8c237e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 45 additions and 20 deletions

View File

@ -136,10 +136,11 @@ 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(
Err(_) => Err(ShellError::CantConvertWithHelp(
"boolean".to_string(),
"string".to_string(),
span,
r#"the strings "true" and "false" can be converted into a bool"#.to_string(),
)),
}
}

View File

@ -260,10 +260,11 @@ fn action(
Ok(d) => Value::Date { val: d, span: head },
Err(reason) => {
return Value::Error {
error: ShellError::CantConvert(
error: ShellError::CantConvertWithHelp(
format!("could not parse as datetime using format '{}'", dt.0),
reason.to_string(),
head,
"you can use `into datetime` without a format string to enable flexible parsing".to_string()
),
}
}

View File

@ -151,10 +151,11 @@ fn string_to_duration(s: &str, span: Span) -> Result<i64, ShellError> {
}
}
Err(ShellError::CantConvert(
Err(ShellError::CantConvertWithHelp(
"duration".to_string(),
"string".to_string(),
span,
"supported units are ns, us, ms, sec, min, hr, day, and wk".to_string(),
))
}

View File

@ -206,8 +206,8 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value {
};
match i64::from_str_radix(&i, radix) {
Ok(n) => Value::Int { val: n, span: head },
Err(reason) => Value::Error {
error: ShellError::CantConvert("".to_string(), reason.to_string(), head),
Err(_reason) => Value::Error {
error: ShellError::CantConvert("int".to_string(), "string".to_string(), head),
},
}
}
@ -218,11 +218,12 @@ fn int_from_string(a_string: &str, span: Span) -> Result<i64, ShellError> {
b if b.starts_with("0b") => {
let num = match i64::from_str_radix(b.trim_start_matches("0b"), 2) {
Ok(n) => n,
Err(reason) => {
return Err(ShellError::CantConvert(
"could not parse as integer".to_string(),
reason.to_string(),
Err(_reason) => {
return Err(ShellError::CantConvertWithHelp(
"int".to_string(),
"string".to_string(),
span,
r#"digits following "0b" can only be 0 or 1"#.to_string(),
))
}
};
@ -231,11 +232,13 @@ fn int_from_string(a_string: &str, span: Span) -> Result<i64, ShellError> {
h if h.starts_with("0x") => {
let num = match i64::from_str_radix(h.trim_start_matches("0x"), 16) {
Ok(n) => n,
Err(reason) => {
return Err(ShellError::CantConvert(
"could not parse as int".to_string(),
reason.to_string(),
Err(_reason) => {
return Err(ShellError::CantConvertWithHelp(
"int".to_string(),
"string".to_string(),
span,
r#"hexadecimal digits following "0x" should be in 0-9, a-f, or A-F"#
.to_string(),
))
}
};
@ -246,7 +249,7 @@ fn int_from_string(a_string: &str, span: Span) -> Result<i64, ShellError> {
Err(_) => match a_string.parse::<f64>() {
Ok(f) => Ok(f as i64),
_ => Err(ShellError::CantConvert(
"into int".to_string(),
"int".to_string(),
"string".to_string(),
span,
)),

View File

@ -257,6 +257,14 @@ pub fn action(
span,
),
},
Value::Binary { .. } => Value::Error {
error: ShellError::CantConvertWithHelp(
"string".into(),
"binary".into(),
span,
"try using the `decode` command".into(),
),
},
x => Value::Error {
error: ShellError::CantConvert(String::from("string"), x.get_type().to_string(), span),
},

View File

@ -193,7 +193,7 @@ fn from_eml(
.with_body_preview(body_preview)
.parse()
.map_err(|_| {
ShellError::CantConvert("structured data from eml".into(), "string".into(), head)
ShellError::CantConvert("structured eml data".into(), "string".into(), head)
})?;
let mut collected = IndexMap::new();

View File

@ -135,7 +135,7 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value {
Value::Error {
error: ShellError::CantConvert(
"i64 sized integer".into(),
"larger than i64".into(),
"value larger than i64".into(),
span,
),
}
@ -201,7 +201,7 @@ fn convert_string_to_value(string_input: String, span: Span) -> Result<Value, Sh
))
}
x => Err(ShellError::CantConvert(
format!("structured data from json ({})", x),
format!("structured json data ({})", x),
"string".into(),
span,
)),

View File

@ -121,7 +121,7 @@ pub fn convert_string_to_value(string_input: String, span: Span) -> Result<Value
Ok(value) => Ok(convert_toml_to_value(&value, span)),
Err(_x) => Err(ShellError::CantConvert(
"structured data from toml".into(),
"structured toml data".into(),
"string".into(),
span,
)),

View File

@ -47,7 +47,8 @@ impl From<ShellError> for LabeledError {
msg,
span: None,
},
ShellError::CantConvert(expected, input, span) => LabeledError {
ShellError::CantConvert(expected, input, span)
| ShellError::CantConvertWithHelp(expected, input, span, _) => LabeledError {
label: format!("Can't convert to {}", expected),
msg: format!("can't convert {} to {}", expected, input),
span: Some(span),

View File

@ -112,6 +112,16 @@ pub enum ShellError {
#[diagnostic(code(nu::shell::cant_convert), url(docsrs))]
CantConvert(String, String, #[label("can't convert {1} to {0}")] Span),
// Identical to above, but with help
#[error("Can't convert to {0}.")]
#[diagnostic(code(nu::shell::cant_convert), url(docsrs), help("{3}"))]
CantConvertWithHelp(
String,
String,
#[label("can't convert {1} to {0}")] Span,
String,
),
#[error("{0} is not representable as a string.")]
#[diagnostic(
code(nu::shell::env_var_not_a_string),

View File

@ -16,7 +16,7 @@ impl Value {
match self {
Value::Int { val, .. } => Ok(*val),
x => Err(ShellError::CantConvert(
"rf64".into(),
"i64".into(),
x.get_type().to_string(),
self.span()?,
)),