diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs index 59e772df64..ce7901a16a 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs @@ -130,13 +130,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { if bits > input_num_type.num_bits() { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to rotate by more than the available bits ({})", + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", input_num_type.num_bits() ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); @@ -171,16 +171,16 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::int(int, span) } Value::Binary { val, .. } => { - let len = val.len(); - if bits > len * 8 { + let max_bits = val.len() * 8; + if bits > max_bits { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to rotate by more than the available bits ({})", - len * 8 + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", + max_bits ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs index 6017d0b5cf..849d6c09c2 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs @@ -134,13 +134,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { if bits > input_num_type.num_bits() { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to rotate by more than the available bits ({})", + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", input_num_type.num_bits() ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); @@ -175,16 +175,16 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::int(int, span) } Value::Binary { val, .. } => { - let len = val.len(); - if bits > len * 8 { + let max_bits = val.len() * 8; + if bits > max_bits { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to rotate by more than the available bits ({})", - len * 8 + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", + max_bits ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs index 155e20a429..799d54c987 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs @@ -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); if !input_num_type.is_permitted_bit_shift(bits) { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to shift by more than the available bits (permitted < {})", + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", input_num_type.num_bits() ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); @@ -188,24 +188,25 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::int(int, span) } 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 // 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( - ShellError::IncorrectValue { - msg: format!( - "Trying to shift by more than the available bits ({})", - val.len() * 8 + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", + max_bits ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); } + let byte_shift = bits / 8; + let bit_shift = bits % 8; + let bytes = if bit_shift == 0 { shift_bytes_left(val, byte_shift) } else { diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs index bc4f165d61..9ee760e27c 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs @@ -132,13 +132,13 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { if !input_num_type.is_permitted_bit_shift(bits) { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to shift by more than the available bits (permitted < {})", + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", input_num_type.num_bits() ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); @@ -157,26 +157,26 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::int(int, span) } 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 // implementation would overflow byte indices leading to unexpected output // lengths - if bits > len * 8 { + let max_bits = val.len() * 8; + if bits > max_bits { return Value::error( - ShellError::IncorrectValue { - msg: format!( - "Trying to shift by more than the available bits ({})", - len * 8 + ShellError::InvalidValue { + valid: format!( + "an integer less than or equal to the available number of bits ({})", + max_bits ), - val_span: bits_span, - call_span: span, + actual: bits.to_string(), + span: bits_span, }, span, ); } + let byte_shift = bits / 8; + let bit_shift = bits % 8; + let bytes = if bit_shift == 0 { shift_bytes_right(val, byte_shift) } else { diff --git a/crates/nu-command/src/bytes/build_.rs b/crates/nu-command/src/bytes/build_.rs index f9ca58b10f..37a6c48ba7 100644 --- a/crates/nu-command/src/bytes/build_.rs +++ b/crates/nu-command/src/bytes/build_.rs @@ -55,10 +55,10 @@ impl Command for BytesBuild { match val { Value::Binary { mut val, .. } => output.append(&mut val), Value::Int { val, .. } => { - let byte: u8 = val.try_into().map_err(|_| ShellError::IncorrectValue { - msg: format!("{val} is out of range for byte"), - val_span, - call_span: call.head, + let byte: u8 = val.try_into().map_err(|_| ShellError::InvalidValue { + valid: "an integer in the range [0, 255]".into(), + actual: val.to_string(), + span: val_span, })?; output.push(byte); } diff --git a/crates/nu-command/src/conversions/into/int.rs b/crates/nu-command/src/conversions/into/int.rs index 0792719fef..a7d1b1e630 100644 --- a/crates/nu-command/src/conversions/into/int.rs +++ b/crates/nu-command/src/conversions/into/int.rs @@ -1,7 +1,7 @@ -use chrono::{FixedOffset, TimeZone}; use nu_cmd_base::input_handler::{operate, CmdArgument}; use nu_engine::command_prelude::*; +use nu_protocol::IntoValue; use nu_utils::get_system_locale; struct Arguments { @@ -294,30 +294,21 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::int(0, span) } } - Value::Date { val, .. } => { - if val - < &FixedOffset::east_opt(0) - .expect("constant") - .with_ymd_and_hms(1677, 9, 21, 0, 12, 44) - .unwrap() - || val - > &FixedOffset::east_opt(0) - .expect("constant") - .with_ymd_and_hms(2262, 4, 11, 23, 47, 16) - .unwrap() - { - 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, + Value::Date { val, .. } => val + .timestamp_nanos_opt() + .map(|nanos| nanos.into_value(span)) + .unwrap_or_else(|| { + Value::error( + ShellError::GenericError { + error: "Date value out of range".into(), + msg: "cannot fit this date's number of nanoseconds into an int".into(), + span: Some(span), + help: None, + inner: Vec::new(), }, span, ) - } else { - Value::int(val.timestamp_nanos_opt().unwrap_or_default(), span) - } - } + }), Value::Duration { val, .. } => Value::int(*val, span), Value::Binary { val, .. } => { use byteorder::{BigEndian, ByteOrder, LittleEndian}; @@ -331,10 +322,10 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { if size > 8 { return Value::error( - ShellError::IncorrectValue { - msg: format!("binary input is too large to convert to int ({size} bytes)"), - val_span, - call_span: span, + ShellError::InvalidValue { + valid: "a binary value with 8 or less bytes".into(), + actual: format!("one with {size} bytes"), + span: val_span, }, span, ); @@ -617,8 +608,8 @@ mod test { } #[rstest] - #[case("2262-04-11T23:47:17+00:00", "DateTime out of range for timestamp")] - #[case("1677-09-21T00:12:43+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", "Date value out of range")] fn datetime_to_int_values_that_fail( #[case] dt_in: DateTime, #[case] err_expected: &str, @@ -635,7 +626,7 @@ mod test { Span::test_data(), ); if let Value::Error { error, .. } = actual { - if let ShellError::IncorrectValue { msg: e, .. } = *error { + if let ShellError::GenericError { error: e, .. } = *error { assert!( e.contains(err_expected), "{e:?} doesn't contain {err_expected}" diff --git a/crates/nu-command/src/conversions/into/record.rs b/crates/nu-command/src/conversions/into/record.rs index 445d81cb86..ffb066316b 100644 --- a/crates/nu-command/src/conversions/into/record.rs +++ b/crates/nu-command/src/conversions/into/record.rs @@ -141,13 +141,10 @@ fn into_record(call: &Call, input: PipelineData) -> Result { - let decl_id = val - .try_into() - .ok() - .map(DeclId::new) - .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); + let decl_id = val.try_into().map_err(|_| ShellError::InvalidValue { + valid: "a non-negative integer".into(), + actual: val.to_string(), + span: target.span(), + })?; + + 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 { error: format!("Can't view IR for `{}`", decl.name()), msg: "not a custom command".into(), @@ -107,10 +113,10 @@ the declaration may not be in scope. Value::Int { val, .. } => { val.try_into() .map(BlockId::new) - .map_err(|_| ShellError::IncorrectValue { - msg: "not a valid block id".into(), - val_span: target.span(), - call_span: call.head, + .map_err(|_| ShellError::InvalidValue { + valid: "a non-negative interger".into(), + actual: val.to_string(), + span: target.span(), })? } // Pass through errors diff --git a/crates/nu-command/src/filesystem/glob.rs b/crates/nu-command/src/filesystem/glob.rs index 1f475efbac..d96c6d7ea0 100644 --- a/crates/nu-command/src/filesystem/glob.rs +++ b/crates/nu-command/src/filesystem/glob.rs @@ -148,16 +148,16 @@ impl Command for Glob { } }; - let glob_pattern = - match glob_pattern_input { - Value::String { val, .. } | Value::Glob { val, .. } => val, - _ => return Err(ShellError::IncorrectValue { - msg: "Incorrect glob pattern supplied to glob. Please use string or glob only." - .to_string(), - val_span: call.head, - call_span: glob_span, - }), - }; + let glob_pattern = match glob_pattern_input { + Value::String { val, .. } | Value::Glob { val, .. } => val, + val => { + return Err(ShellError::RuntimeTypeMismatch { + expected: Type::custom("string or glob"), + actual: val.get_type(), + span: val.span(), + }); + } + }; if glob_pattern.is_empty() { return Err(ShellError::GenericError { diff --git a/crates/nu-command/src/filters/chunks.rs b/crates/nu-command/src/filters/chunks.rs index 4db436ca25..2f9da05d0f 100644 --- a/crates/nu-command/src/filters/chunks.rs +++ b/crates/nu-command/src/filters/chunks.rs @@ -83,19 +83,16 @@ impl Command for Chunks { input: PipelineData, ) -> Result { let head = call.head; - let chunk_size: Value = call.req(engine_state, stack, 0)?; + let chunk_size: Spanned = call.req(engine_state, stack, 0)?; - let size = - usize::try_from(chunk_size.as_int()?).map_err(|_| ShellError::NeedsPositiveValue { - span: chunk_size.span(), + let size = usize::try_from(chunk_size.item) + .and_then(NonZeroUsize::try_from) + .map_err(|_| ShellError::InvalidValue { + valid: "an integer greater than 0".into(), + actual: chunk_size.item.to_string(), + span: chunk_size.span, })?; - let size = NonZeroUsize::try_from(size).map_err(|_| ShellError::IncorrectValue { - msg: "`chunk_size` cannot be zero".into(), - val_span: chunk_size.span(), - call_span: head, - })?; - chunks(engine_state, input, size, head) } } diff --git a/crates/nu-command/src/filters/window.rs b/crates/nu-command/src/filters/window.rs index 65ce2b0aee..2088c84b4a 100644 --- a/crates/nu-command/src/filters/window.rs +++ b/crates/nu-command/src/filters/window.rs @@ -82,33 +82,26 @@ impl Command for Window { input: PipelineData, ) -> Result { let head = call.head; - let window_size: Value = call.req(engine_state, stack, 0)?; - let stride: Option = call.get_flag(engine_state, stack, "stride")?; + let window_size: Spanned = call.req(engine_state, stack, 0)?; + let stride: Option> = call.get_flag(engine_state, stack, "stride")?; let remainder = call.has_flag(engine_state, stack, "remainder")?; - let size = - usize::try_from(window_size.as_int()?).map_err(|_| ShellError::NeedsPositiveValue { - span: window_size.span(), + let size = usize::try_from(window_size.item) + .and_then(NonZeroUsize::try_from) + .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 { - msg: "`window_size` cannot be zero".into(), - val_span: window_size.span(), - call_span: head, - })?; - - let stride = if let Some(stride_val) = stride { - 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, - })? + let stride = if let Some(stride) = stride { + usize::try_from(stride.item) + .and_then(NonZeroUsize::try_from) + .map_err(|_| ShellError::InvalidValue { + valid: "an integer greater than 0".into(), + actual: stride.item.to_string(), + span: stride.span, + })? } else { NonZeroUsize::MIN }; diff --git a/crates/nu-command/src/formats/to/delimited.rs b/crates/nu-command/src/formats/to/delimited.rs index ac04739a3d..4494004f0d 100644 --- a/crates/nu-command/src/formats/to/delimited.rs +++ b/crates/nu-command/src/formats/to/delimited.rs @@ -100,10 +100,10 @@ pub fn to_delimited_data( .with_content_type(content_type), ); - let separator = u8::try_from(separator.item).map_err(|_| ShellError::IncorrectValue { - msg: "separator must be an ASCII character".into(), - val_span: separator.span, - call_span: head, + let separator = u8::try_from(separator.item).map_err(|_| ShellError::InvalidValue { + valid: "an ASCII character".into(), + actual: separator.item.to_string(), + span: separator.span, })?; // Check to ensure the input is likely one of our supported types first. We can't check a stream diff --git a/crates/nu-command/src/network/http/client.rs b/crates/nu-command/src/network/http/client.rs index 8dd4cc5601..f169cc8556 100644 --- a/crates/nu-command/src/network/http/client.rs +++ b/crates/nu-command/src/network/http/client.rs @@ -313,11 +313,13 @@ fn send_form_request( match body { Value::List { ref vals, .. } => { if vals.len() % 2 != 0 { - return Err(ShellErrorOrRequestError::ShellError(ShellError::IncorrectValue { - msg: "Body type 'list' for form requests requires paired values. E.g.: [foo, 10]".into(), - val_span: body.span(), - call_span: span, - })); + return Err(ShellErrorOrRequestError::ShellError( + ShellError::InvalidValue { + valid: "a list with an even number of elements".into(), + actual: format!("a list with {} elements", vals.len()), + span: body.span(), + }, + )); } let data = vals diff --git a/crates/nu-command/src/platform/ulimit.rs b/crates/nu-command/src/platform/ulimit.rs index 871633efc4..92b6a3a51d 100644 --- a/crates/nu-command/src/platform/ulimit.rs +++ b/crates/nu-command/src/platform/ulimit.rs @@ -338,10 +338,9 @@ fn set_limits( res: &ResourceInfo, soft: bool, hard: bool, - call_span: Span, ) -> Result<(), ShellError> { 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 { hard_limit = new_limit; @@ -429,14 +428,14 @@ fn parse_limit( soft: bool, soft_limit: rlim_t, hard_limit: rlim_t, - call_span: Span, ) -> Result { + let span = limit_value.span(); match limit_value { - Value::Int { val, internal_span } => { + Value::Int { val, .. } => { let value = rlim_t::try_from(*val).map_err(|e| ShellError::CantConvert { to_type: "rlim_t".into(), from_type: "i64".into(), - span: *internal_span, + span, help: Some(e.to_string()), })?; @@ -447,25 +446,25 @@ fn parse_limit( Ok(limit) } } - Value::Filesize { val, internal_span } => { + Value::Filesize { val, .. } => { if res.multiplier != 1024 { return Err(ShellError::TypeMismatch { err_message: format!( "filesize is not compatible with resource {:?}", res.resource ), - span: *internal_span, + span, }); } rlim_t::try_from(*val).map_err(|e| ShellError::CantConvert { to_type: "rlim_t".into(), from_type: "i64".into(), - span: *internal_span, + span, help: Some(e.to_string()), }) } - Value::String { val, internal_span } => { + Value::String { val, .. } => { if val == "unlimited" { Ok(RLIM_INFINITY) } else if val == "soft" { @@ -477,10 +476,10 @@ fn parse_limit( } else if val == "hard" { Ok(hard_limit) } else { - return Err(ShellError::IncorrectValue { - msg: "Only unlimited, soft and hard are supported for strings".into(), - val_span: *internal_span, - call_span, + return Err(ShellError::InvalidValue { + valid: "'unlimited', 'soft', or 'hard'".into(), + actual: format!("'{val}'"), + span, }); } } @@ -489,7 +488,7 @@ fn parse_limit( "string, int or filesize required, you provide {}", limit_value.get_type() ), - span: limit_value.span(), + span, }), } } @@ -544,7 +543,7 @@ impl Command for ULimit { for res in RESOURCE_ARRAY.iter() { 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 { set_default_limit = false; @@ -555,7 +554,7 @@ impl Command for ULimit { // Set `RLIMIT_FSIZE` limit if no resource flag provided. if set_default_limit { let res = ResourceInfo::default(); - set_limits(&limit_value, &res, hard, soft, call.head)?; + set_limits(&limit_value, &res, hard, soft)?; } Ok(PipelineData::Empty) diff --git a/crates/nu-command/src/strings/base/mod.rs b/crates/nu-command/src/strings/base/mod.rs index 6a30c0d21f..82e898590f 100644 --- a/crates/nu-command/src/strings/base/mod.rs +++ b/crates/nu-command/src/strings/base/mod.rs @@ -24,10 +24,13 @@ pub fn decode( let output = match encoding.decode(input_str.as_bytes()) { Ok(output) => output, 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(), - val_span: input_span, - call_span, + span: Some(call_span), + help: None, + inner: Vec::new(), }); } }; diff --git a/crates/nu-command/src/strings/str_/replace.rs b/crates/nu-command/src/strings/str_/replace.rs index a893a88c62..e20d39da97 100644 --- a/crates/nu-command/src/strings/str_/replace.rs +++ b/crates/nu-command/src/strings/str_/replace.rs @@ -249,9 +249,8 @@ fn action( false => "", }; let regex_string = flags.to_string() + find_str; - let regex = Regex::new(®ex_string); - match regex { + match Regex::new(®ex_string) { Ok(re) => { if *all { Value::string( @@ -278,10 +277,12 @@ fn action( } } Err(e) => Value::error( - ShellError::IncorrectValue { - msg: format!("Regex error: {e}"), - val_span: find.span, - call_span: head, + ShellError::GenericError { + error: "Failed to create regex".into(), + msg: e.to_string(), + span: Some(find.span), + help: None, + inner: Vec::new(), }, find.span, ), diff --git a/crates/nu-protocol/src/errors/shell_error.rs b/crates/nu-protocol/src/errors/shell_error.rs index 0f609061d6..2180943ecb 100644 --- a/crates/nu-protocol/src/errors/shell_error.rs +++ b/crates/nu-protocol/src/errors/shell_error.rs @@ -135,21 +135,6 @@ pub enum ShellError { 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. /// /// ## Resolution diff --git a/crates/nu_plugin_polars/src/dataframe/command/core/save/avro.rs b/crates/nu_plugin_polars/src/dataframe/command/core/save/avro.rs index ef5c0cdca2..856d198c22 100644 --- a/crates/nu_plugin_polars/src/dataframe/command/core/save/avro.rs +++ b/crates/nu_plugin_polars/src/dataframe/command/core/save/avro.rs @@ -17,10 +17,10 @@ fn get_compression(call: &EvaluatedCall) -> Result, Shel match compression.as_ref() { "snappy" => Ok(Some(AvroCompression::Snappy)), "deflate" => Ok(Some(AvroCompression::Deflate)), - _ => Err(ShellError::IncorrectValue { - msg: "compression must be one of deflate or snappy".to_string(), - val_span: span, - call_span: span, + _ => Err(ShellError::InvalidValue { + valid: "'deflate' or 'snappy'".into(), + actual: format!("'{compression}'"), + span, }), } } else {