Replace IncorrectValue with InvalidValue

This commit is contained in:
Ian Manske 2024-09-29 20:47:00 -07:00
parent 1f47d72e86
commit 9a2a86399c
18 changed files with 183 additions and 208 deletions

View File

@ -130,13 +130,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
if bits > input_num_type.num_bits() { if bits > input_num_type.num_bits() {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to rotate by more than the available bits ({})", "an integer less than or equal to the available number of bits ({})",
input_num_type.num_bits() input_num_type.num_bits()
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );
@ -171,16 +171,16 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
Value::int(int, span) Value::int(int, span)
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
let len = val.len(); let max_bits = val.len() * 8;
if bits > len * 8 { if bits > max_bits {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to rotate by more than the available bits ({})", "an integer less than or equal to the available number of bits ({})",
len * 8 max_bits
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );

View File

@ -134,13 +134,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
if bits > input_num_type.num_bits() { if bits > input_num_type.num_bits() {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to rotate by more than the available bits ({})", "an integer less than or equal to the available number of bits ({})",
input_num_type.num_bits() input_num_type.num_bits()
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );
@ -175,16 +175,16 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
Value::int(int, span) Value::int(int, span)
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
let len = val.len(); let max_bits = val.len() * 8;
if bits > len * 8 { if bits > max_bits {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to rotate by more than the available bits ({})", "an integer less than or equal to the available number of bits ({})",
len * 8 max_bits
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );

View File

@ -145,13 +145,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
let input_num_type = get_input_num_type(val, signed, number_size); let input_num_type = get_input_num_type(val, signed, number_size);
if !input_num_type.is_permitted_bit_shift(bits) { if !input_num_type.is_permitted_bit_shift(bits) {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to shift by more than the available bits (permitted < {})", "an integer less than or equal to the available number of bits ({})",
input_num_type.num_bits() input_num_type.num_bits()
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );
@ -188,24 +188,25 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
Value::int(int, span) Value::int(int, span)
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
let byte_shift = bits / 8;
let bit_shift = bits % 8;
// This is purely for symmetry with the int case and the fact that the // This is purely for symmetry with the int case and the fact that the
// shift right implementation in its current form panicked with an overflow // shift right implementation in its current form panicked with an overflow
if bits > val.len() * 8 { let max_bits = val.len() * 8;
if bits > max_bits {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to shift by more than the available bits ({})", "an integer less than or equal to the available number of bits ({})",
val.len() * 8 max_bits
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );
} }
let byte_shift = bits / 8;
let bit_shift = bits % 8;
let bytes = if bit_shift == 0 { let bytes = if bit_shift == 0 {
shift_bytes_left(val, byte_shift) shift_bytes_left(val, byte_shift)
} else { } else {

View File

@ -132,13 +132,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
if !input_num_type.is_permitted_bit_shift(bits) { if !input_num_type.is_permitted_bit_shift(bits) {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to shift by more than the available bits (permitted < {})", "an integer less than or equal to the available number of bits ({})",
input_num_type.num_bits() input_num_type.num_bits()
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );
@ -157,26 +157,26 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
Value::int(int, span) Value::int(int, span)
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
let byte_shift = bits / 8;
let bit_shift = bits % 8;
let len = val.len();
// This check is done for symmetry with the int case and the previous // This check is done for symmetry with the int case and the previous
// implementation would overflow byte indices leading to unexpected output // implementation would overflow byte indices leading to unexpected output
// lengths // lengths
if bits > len * 8 { let max_bits = val.len() * 8;
if bits > max_bits {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!( valid: format!(
"Trying to shift by more than the available bits ({})", "an integer less than or equal to the available number of bits ({})",
len * 8 max_bits
), ),
val_span: bits_span, actual: bits.to_string(),
call_span: span, span: bits_span,
}, },
span, span,
); );
} }
let byte_shift = bits / 8;
let bit_shift = bits % 8;
let bytes = if bit_shift == 0 { let bytes = if bit_shift == 0 {
shift_bytes_right(val, byte_shift) shift_bytes_right(val, byte_shift)
} else { } else {

View File

@ -55,10 +55,10 @@ impl Command for BytesBuild {
match val { match val {
Value::Binary { mut val, .. } => output.append(&mut val), Value::Binary { mut val, .. } => output.append(&mut val),
Value::Int { val, .. } => { Value::Int { val, .. } => {
let byte: u8 = val.try_into().map_err(|_| ShellError::IncorrectValue { let byte: u8 = val.try_into().map_err(|_| ShellError::InvalidValue {
msg: format!("{val} is out of range for byte"), valid: "an integer in the range [0, 255]".into(),
val_span, actual: val.to_string(),
call_span: call.head, span: val_span,
})?; })?;
output.push(byte); output.push(byte);
} }

View File

@ -1,7 +1,7 @@
use chrono::{FixedOffset, TimeZone};
use nu_cmd_base::input_handler::{operate, CmdArgument}; use nu_cmd_base::input_handler::{operate, CmdArgument};
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use nu_protocol::IntoValue;
use nu_utils::get_system_locale; use nu_utils::get_system_locale;
struct Arguments { struct Arguments {
@ -294,30 +294,21 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
Value::int(0, span) Value::int(0, span)
} }
} }
Value::Date { val, .. } => { Value::Date { val, .. } => val
if val .timestamp_nanos_opt()
< &FixedOffset::east_opt(0) .map(|nanos| nanos.into_value(span))
.expect("constant") .unwrap_or_else(|| {
.with_ymd_and_hms(1677, 9, 21, 0, 12, 44) Value::error(
.unwrap() ShellError::GenericError {
|| val error: "Date value out of range".into(),
> &FixedOffset::east_opt(0) msg: "cannot fit this date's number of nanoseconds into an int".into(),
.expect("constant") span: Some(span),
.with_ymd_and_hms(2262, 4, 11, 23, 47, 16) help: None,
.unwrap() inner: Vec::new(),
{
Value::error (
ShellError::IncorrectValue {
msg: "DateTime out of range for timestamp: 1677-09-21T00:12:43Z to 2262-04-11T23:47:16".to_string(),
val_span,
call_span: span,
}, },
span, span,
) )
} else { }),
Value::int(val.timestamp_nanos_opt().unwrap_or_default(), span)
}
}
Value::Duration { val, .. } => Value::int(*val, span), Value::Duration { val, .. } => Value::int(*val, span),
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
use byteorder::{BigEndian, ByteOrder, LittleEndian}; use byteorder::{BigEndian, ByteOrder, LittleEndian};
@ -331,10 +322,10 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
if size > 8 { if size > 8 {
return Value::error( return Value::error(
ShellError::IncorrectValue { ShellError::InvalidValue {
msg: format!("binary input is too large to convert to int ({size} bytes)"), valid: "a binary value with 8 or less bytes".into(),
val_span, actual: format!("one with {size} bytes"),
call_span: span, span: val_span,
}, },
span, span,
); );
@ -617,8 +608,8 @@ mod test {
} }
#[rstest] #[rstest]
#[case("2262-04-11T23:47:17+00:00", "DateTime out of range for timestamp")] #[case("2262-04-11T23:47:17+00:00", "Date value out of range")]
#[case("1677-09-21T00:12:43+00:00", "DateTime out of range for timestamp")] #[case("1677-09-21T00:12:43+00:00", "Date value out of range")]
fn datetime_to_int_values_that_fail( fn datetime_to_int_values_that_fail(
#[case] dt_in: DateTime<FixedOffset>, #[case] dt_in: DateTime<FixedOffset>,
#[case] err_expected: &str, #[case] err_expected: &str,
@ -635,7 +626,7 @@ mod test {
Span::test_data(), Span::test_data(),
); );
if let Value::Error { error, .. } = actual { if let Value::Error { error, .. } = actual {
if let ShellError::IncorrectValue { msg: e, .. } = *error { if let ShellError::GenericError { error: e, .. } = *error {
assert!( assert!(
e.contains(err_expected), e.contains(err_expected),
"{e:?} doesn't contain {err_expected}" "{e:?} doesn't contain {err_expected}"

View File

@ -141,13 +141,10 @@ fn into_record(call: &Call, input: PipelineData) -> Result<PipelineData, ShellEr
let (val, key) = vals.pop().zip(vals.pop()).expect("length is < 2"); let (val, key) = vals.pop().zip(vals.pop()).expect("length is < 2");
record.insert(key.coerce_into_string()?, val); record.insert(key.coerce_into_string()?, val);
} else { } else {
return Err(ShellError::IncorrectValue { return Err(ShellError::InvalidValue {
msg: format!( valid: "a list with 2 elements".into(),
"expected inner list with two elements, but found {} element(s)", actual: format!("a list with {} element(s)", vals.len()),
vals.len() span,
),
val_span: span,
call_span: call.head,
}); });
} }
expected_type = Some(ExpectedType::Pair); expected_type = Some(ExpectedType::Pair);

View File

@ -84,17 +84,23 @@ the declaration may not be in scope.
} }
// Decl by ID - IR dump always shows name of decl, but sometimes it isn't in scope // Decl by ID - IR dump always shows name of decl, but sometimes it isn't in scope
Value::Int { val, .. } if is_decl_id => { Value::Int { val, .. } if is_decl_id => {
let decl_id = val let decl_id = val.try_into().map_err(|_| ShellError::InvalidValue {
.try_into() valid: "a non-negative integer".into(),
.ok() actual: val.to_string(),
.map(DeclId::new) span: target.span(),
.filter(|id| id.get() < engine_state.num_decls())
.ok_or_else(|| ShellError::IncorrectValue {
msg: "not a valid decl id".into(),
val_span: target.span(),
call_span: call.head,
})?; })?;
let decl = engine_state.get_decl(decl_id);
if decl_id >= engine_state.num_decls() {
return Err(ShellError::GenericError {
error: format!("Unknown decl ID: {decl_id}"),
msg: "ensure the decl ID is correct and try again".into(),
span: Some(target.span()),
help: None,
inner: vec![],
});
};
let decl = engine_state.get_decl(DeclId::new(decl_id));
decl.block_id().ok_or_else(|| ShellError::GenericError { decl.block_id().ok_or_else(|| ShellError::GenericError {
error: format!("Can't view IR for `{}`", decl.name()), error: format!("Can't view IR for `{}`", decl.name()),
msg: "not a custom command".into(), msg: "not a custom command".into(),
@ -107,10 +113,10 @@ the declaration may not be in scope.
Value::Int { val, .. } => { Value::Int { val, .. } => {
val.try_into() val.try_into()
.map(BlockId::new) .map(BlockId::new)
.map_err(|_| ShellError::IncorrectValue { .map_err(|_| ShellError::InvalidValue {
msg: "not a valid block id".into(), valid: "a non-negative interger".into(),
val_span: target.span(), actual: val.to_string(),
call_span: call.head, span: target.span(),
})? })?
} }
// Pass through errors // Pass through errors

View File

@ -148,15 +148,15 @@ impl Command for Glob {
} }
}; };
let glob_pattern = let glob_pattern = match glob_pattern_input {
match glob_pattern_input {
Value::String { val, .. } | Value::Glob { val, .. } => val, Value::String { val, .. } | Value::Glob { val, .. } => val,
_ => return Err(ShellError::IncorrectValue { val => {
msg: "Incorrect glob pattern supplied to glob. Please use string or glob only." return Err(ShellError::RuntimeTypeMismatch {
.to_string(), expected: Type::custom("string or glob"),
val_span: call.head, actual: val.get_type(),
call_span: glob_span, span: val.span(),
}), });
}
}; };
if glob_pattern.is_empty() { if glob_pattern.is_empty() {

View File

@ -83,17 +83,14 @@ impl Command for Chunks {
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let head = call.head; let head = call.head;
let chunk_size: Value = call.req(engine_state, stack, 0)?; let chunk_size: Spanned<i64> = call.req(engine_state, stack, 0)?;
let size = let size = usize::try_from(chunk_size.item)
usize::try_from(chunk_size.as_int()?).map_err(|_| ShellError::NeedsPositiveValue { .and_then(NonZeroUsize::try_from)
span: chunk_size.span(), .map_err(|_| ShellError::InvalidValue {
})?; valid: "an integer greater than 0".into(),
actual: chunk_size.item.to_string(),
let size = NonZeroUsize::try_from(size).map_err(|_| ShellError::IncorrectValue { span: chunk_size.span,
msg: "`chunk_size` cannot be zero".into(),
val_span: chunk_size.span(),
call_span: head,
})?; })?;
chunks(engine_state, input, size, head) chunks(engine_state, input, size, head)

View File

@ -82,32 +82,25 @@ impl Command for Window {
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let head = call.head; let head = call.head;
let window_size: Value = call.req(engine_state, stack, 0)?; let window_size: Spanned<i64> = call.req(engine_state, stack, 0)?;
let stride: Option<Value> = call.get_flag(engine_state, stack, "stride")?; let stride: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "stride")?;
let remainder = call.has_flag(engine_state, stack, "remainder")?; let remainder = call.has_flag(engine_state, stack, "remainder")?;
let size = let size = usize::try_from(window_size.item)
usize::try_from(window_size.as_int()?).map_err(|_| ShellError::NeedsPositiveValue { .and_then(NonZeroUsize::try_from)
span: window_size.span(), .map_err(|_| ShellError::InvalidValue {
valid: "an integer greater than 0".into(),
actual: window_size.item.to_string(),
span: window_size.span,
})?; })?;
let size = NonZeroUsize::try_from(size).map_err(|_| ShellError::IncorrectValue { let stride = if let Some(stride) = stride {
msg: "`window_size` cannot be zero".into(), usize::try_from(stride.item)
val_span: window_size.span(), .and_then(NonZeroUsize::try_from)
call_span: head, .map_err(|_| ShellError::InvalidValue {
})?; valid: "an integer greater than 0".into(),
actual: stride.item.to_string(),
let stride = if let Some(stride_val) = stride { span: stride.span,
let stride = usize::try_from(stride_val.as_int()?).map_err(|_| {
ShellError::NeedsPositiveValue {
span: stride_val.span(),
}
})?;
NonZeroUsize::try_from(stride).map_err(|_| ShellError::IncorrectValue {
msg: "`stride` cannot be zero".into(),
val_span: stride_val.span(),
call_span: head,
})? })?
} else { } else {
NonZeroUsize::MIN NonZeroUsize::MIN

View File

@ -100,10 +100,10 @@ pub fn to_delimited_data(
.with_content_type(content_type), .with_content_type(content_type),
); );
let separator = u8::try_from(separator.item).map_err(|_| ShellError::IncorrectValue { let separator = u8::try_from(separator.item).map_err(|_| ShellError::InvalidValue {
msg: "separator must be an ASCII character".into(), valid: "an ASCII character".into(),
val_span: separator.span, actual: separator.item.to_string(),
call_span: head, span: separator.span,
})?; })?;
// Check to ensure the input is likely one of our supported types first. We can't check a stream // Check to ensure the input is likely one of our supported types first. We can't check a stream

View File

@ -313,11 +313,13 @@ fn send_form_request(
match body { match body {
Value::List { ref vals, .. } => { Value::List { ref vals, .. } => {
if vals.len() % 2 != 0 { if vals.len() % 2 != 0 {
return Err(ShellErrorOrRequestError::ShellError(ShellError::IncorrectValue { return Err(ShellErrorOrRequestError::ShellError(
msg: "Body type 'list' for form requests requires paired values. E.g.: [foo, 10]".into(), ShellError::InvalidValue {
val_span: body.span(), valid: "a list with an even number of elements".into(),
call_span: span, actual: format!("a list with {} elements", vals.len()),
})); span: body.span(),
},
));
} }
let data = vals let data = vals

View File

@ -338,10 +338,9 @@ fn set_limits(
res: &ResourceInfo, res: &ResourceInfo,
soft: bool, soft: bool,
hard: bool, hard: bool,
call_span: Span,
) -> Result<(), ShellError> { ) -> Result<(), ShellError> {
let (mut soft_limit, mut hard_limit) = getrlimit(res.resource)?; let (mut soft_limit, mut hard_limit) = getrlimit(res.resource)?;
let new_limit = parse_limit(limit_value, res, soft, soft_limit, hard_limit, call_span)?; let new_limit = parse_limit(limit_value, res, soft, soft_limit, hard_limit)?;
if hard { if hard {
hard_limit = new_limit; hard_limit = new_limit;
@ -429,14 +428,14 @@ fn parse_limit(
soft: bool, soft: bool,
soft_limit: rlim_t, soft_limit: rlim_t,
hard_limit: rlim_t, hard_limit: rlim_t,
call_span: Span,
) -> Result<rlim_t, ShellError> { ) -> Result<rlim_t, ShellError> {
let span = limit_value.span();
match limit_value { match limit_value {
Value::Int { val, internal_span } => { Value::Int { val, .. } => {
let value = rlim_t::try_from(*val).map_err(|e| ShellError::CantConvert { let value = rlim_t::try_from(*val).map_err(|e| ShellError::CantConvert {
to_type: "rlim_t".into(), to_type: "rlim_t".into(),
from_type: "i64".into(), from_type: "i64".into(),
span: *internal_span, span,
help: Some(e.to_string()), help: Some(e.to_string()),
})?; })?;
@ -447,25 +446,25 @@ fn parse_limit(
Ok(limit) Ok(limit)
} }
} }
Value::Filesize { val, internal_span } => { Value::Filesize { val, .. } => {
if res.multiplier != 1024 { if res.multiplier != 1024 {
return Err(ShellError::TypeMismatch { return Err(ShellError::TypeMismatch {
err_message: format!( err_message: format!(
"filesize is not compatible with resource {:?}", "filesize is not compatible with resource {:?}",
res.resource res.resource
), ),
span: *internal_span, span,
}); });
} }
rlim_t::try_from(*val).map_err(|e| ShellError::CantConvert { rlim_t::try_from(*val).map_err(|e| ShellError::CantConvert {
to_type: "rlim_t".into(), to_type: "rlim_t".into(),
from_type: "i64".into(), from_type: "i64".into(),
span: *internal_span, span,
help: Some(e.to_string()), help: Some(e.to_string()),
}) })
} }
Value::String { val, internal_span } => { Value::String { val, .. } => {
if val == "unlimited" { if val == "unlimited" {
Ok(RLIM_INFINITY) Ok(RLIM_INFINITY)
} else if val == "soft" { } else if val == "soft" {
@ -477,10 +476,10 @@ fn parse_limit(
} else if val == "hard" { } else if val == "hard" {
Ok(hard_limit) Ok(hard_limit)
} else { } else {
return Err(ShellError::IncorrectValue { return Err(ShellError::InvalidValue {
msg: "Only unlimited, soft and hard are supported for strings".into(), valid: "'unlimited', 'soft', or 'hard'".into(),
val_span: *internal_span, actual: format!("'{val}'"),
call_span, span,
}); });
} }
} }
@ -489,7 +488,7 @@ fn parse_limit(
"string, int or filesize required, you provide {}", "string, int or filesize required, you provide {}",
limit_value.get_type() limit_value.get_type()
), ),
span: limit_value.span(), span,
}), }),
} }
} }
@ -544,7 +543,7 @@ impl Command for ULimit {
for res in RESOURCE_ARRAY.iter() { for res in RESOURCE_ARRAY.iter() {
if call.has_flag(engine_state, stack, res.name)? { if call.has_flag(engine_state, stack, res.name)? {
set_limits(&limit_value, res, soft, hard, call.head)?; set_limits(&limit_value, res, soft, hard)?;
if set_default_limit { if set_default_limit {
set_default_limit = false; set_default_limit = false;
@ -555,7 +554,7 @@ impl Command for ULimit {
// Set `RLIMIT_FSIZE` limit if no resource flag provided. // Set `RLIMIT_FSIZE` limit if no resource flag provided.
if set_default_limit { if set_default_limit {
let res = ResourceInfo::default(); let res = ResourceInfo::default();
set_limits(&limit_value, &res, hard, soft, call.head)?; set_limits(&limit_value, &res, hard, soft)?;
} }
Ok(PipelineData::Empty) Ok(PipelineData::Empty)

View File

@ -24,10 +24,13 @@ pub fn decode(
let output = match encoding.decode(input_str.as_bytes()) { let output = match encoding.decode(input_str.as_bytes()) {
Ok(output) => output, Ok(output) => output,
Err(err) => { Err(err) => {
return Err(ShellError::IncorrectValue { // TODO: convert/map each possible `DecodeError` case.
return Err(ShellError::GenericError {
error: "Failed to decode".into(),
msg: err.to_string(), msg: err.to_string(),
val_span: input_span, span: Some(call_span),
call_span, help: None,
inner: Vec::new(),
}); });
} }
}; };

View File

@ -249,9 +249,8 @@ fn action(
false => "", false => "",
}; };
let regex_string = flags.to_string() + find_str; let regex_string = flags.to_string() + find_str;
let regex = Regex::new(&regex_string);
match regex { match Regex::new(&regex_string) {
Ok(re) => { Ok(re) => {
if *all { if *all {
Value::string( Value::string(
@ -278,10 +277,12 @@ fn action(
} }
} }
Err(e) => Value::error( Err(e) => Value::error(
ShellError::IncorrectValue { ShellError::GenericError {
msg: format!("Regex error: {e}"), error: "Failed to create regex".into(),
val_span: find.span, msg: e.to_string(),
call_span: head, span: Some(find.span),
help: None,
inner: Vec::new(),
}, },
find.span, find.span,
), ),

View File

@ -135,21 +135,6 @@ pub enum ShellError {
span: Span, span: Span,
}, },
/// A command received an argument with correct type but incorrect value.
///
/// ## Resolution
///
/// Correct the argument value before passing it in or change the command.
#[error("Incorrect value.")]
#[diagnostic(code(nu::shell::incorrect_value))]
IncorrectValue {
msg: String,
#[label = "{msg}"]
val_span: Span,
#[label = "encountered here"]
call_span: Span,
},
/// This value cannot be used with this operator. /// This value cannot be used with this operator.
/// ///
/// ## Resolution /// ## Resolution

View File

@ -17,10 +17,10 @@ fn get_compression(call: &EvaluatedCall) -> Result<Option<AvroCompression>, Shel
match compression.as_ref() { match compression.as_ref() {
"snappy" => Ok(Some(AvroCompression::Snappy)), "snappy" => Ok(Some(AvroCompression::Snappy)),
"deflate" => Ok(Some(AvroCompression::Deflate)), "deflate" => Ok(Some(AvroCompression::Deflate)),
_ => Err(ShellError::IncorrectValue { _ => Err(ShellError::InvalidValue {
msg: "compression must be one of deflate or snappy".to_string(), valid: "'deflate' or 'snappy'".into(),
val_span: span, actual: format!("'{compression}'"),
call_span: span, span,
}), }),
} }
} else { } else {