mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 10:25:42 +02:00
Move Value to helpers, separate span call (#10121)
# Description As part of the refactor to split spans off of Value, this moves to using helper functions to create values, and using `.span()` instead of matching span out of Value directly. Hoping to get a few more helping hands to finish this, as there are a lot of commands to update :) # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> --------- Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com> Co-authored-by: WindSoilder <windsoilder@outlook.com>
This commit is contained in:
@ -68,32 +68,30 @@ impl Command for BitsAnd {
|
||||
Example {
|
||||
description: "Apply logical and to a list of numbers",
|
||||
example: "[4 3 2] | bits and 2",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(0), Value::test_int(2), Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_int(0), Value::test_int(2), Value::test_int(2)],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, target: i64, head: Span) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => Value::Int {
|
||||
val: val & target,
|
||||
span,
|
||||
},
|
||||
Value::Int { val, .. } => Value::int(val & target, span),
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,16 +34,16 @@ impl Command for Bits {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(
|
||||
Ok(Value::string(
|
||||
get_full_help(
|
||||
&Bits.signature(),
|
||||
&Bits.examples(),
|
||||
engine_state,
|
||||
stack,
|
||||
self.is_parser_keyword(),
|
||||
),
|
||||
span: call.head,
|
||||
}
|
||||
call.head,
|
||||
)
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -71,58 +71,51 @@ impl Command for BitsInto {
|
||||
Example {
|
||||
description: "convert a binary value into a string, padded to 8 places with 0s",
|
||||
example: "01b | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "00000001".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("00000001",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "convert an int into a string, padded to 8 places with 0s",
|
||||
example: "1 | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "00000001".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("00000001",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "convert a filesize value into a string, padded to 8 places with 0s",
|
||||
example: "1b | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "00000001".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("00000001",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "convert a duration value into a string, padded to 8 places with 0s",
|
||||
example: "1ns | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "00000001".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("00000001",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "convert a boolean value into a string, padded to 8 places with 0s",
|
||||
example: "true | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "00000001".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("00000001",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "convert a datetime value into a string, padded to 8 places with 0s",
|
||||
example: "2023-04-17T01:02:03 | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "01001101 01101111 01101110 00100000 01000001 01110000 01110010 00100000 00110001 00110111 00100000 00110000 00110001 00111010 00110000 00110010 00111010 00110000 00110011 00100000 00110010 00110000 00110010 00110011".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("01001101 01101111 01101110 00100000 01000001 01110000 01110010 00100000 00110001 00110111 00100000 00110000 00110001 00111010 00110000 00110010 00111010 00110000 00110011 00100000 00110010 00110000 00110010 00110011",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "convert a string into a raw binary string, padded with 0s to 8 places",
|
||||
example: "'nushell.sh' | into bits",
|
||||
result: Some(Value::String {
|
||||
val: "01101110 01110101 01110011 01101000 01100101 01101100 01101100 00101110 01110011 01101000".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::string("01101110 01110101 01110011 01101000 01100101 01101100 01101100 00101110 01110011 01101000",
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -139,22 +132,16 @@ fn into_bits(
|
||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||
|
||||
match input {
|
||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(Value::Binary {
|
||||
val: vec![],
|
||||
span: head,
|
||||
PipelineData::ExternalStream { stdout: None, .. } => {
|
||||
Ok(Value::binary(vec![], head).into_pipeline_data())
|
||||
}
|
||||
.into_pipeline_data()),
|
||||
PipelineData::ExternalStream {
|
||||
stdout: Some(stream),
|
||||
..
|
||||
} => {
|
||||
// TODO: in the future, we may want this to stream out, converting each to bytes
|
||||
let output = stream.into_bytes()?;
|
||||
Ok(Value::Binary {
|
||||
val: output.item,
|
||||
span: head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
Ok(Value::binary(output.item, head).into_pipeline_data())
|
||||
}
|
||||
_ => {
|
||||
let args = Arguments { cell_paths };
|
||||
@ -170,40 +157,28 @@ fn convert_to_smallest_number_type(num: i64, span: Span) -> Value {
|
||||
for ch in bytes {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
} else if let Some(v) = num.to_i16() {
|
||||
let bytes = v.to_ne_bytes();
|
||||
let mut raw_string = "".to_string();
|
||||
for ch in bytes {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
} else if let Some(v) = num.to_i32() {
|
||||
let bytes = v.to_ne_bytes();
|
||||
let mut raw_string = "".to_string();
|
||||
for ch in bytes {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
} else {
|
||||
let bytes = num.to_ne_bytes();
|
||||
let mut raw_string = "".to_string();
|
||||
for ch in bytes {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,10 +189,7 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value {
|
||||
for ch in val {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
}
|
||||
Value::Int { val, .. } => convert_to_smallest_number_type(*val, span),
|
||||
Value::Filesize { val, .. } => convert_to_smallest_number_type(*val, span),
|
||||
@ -228,10 +200,7 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value {
|
||||
for ch in raw_bytes {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
}
|
||||
Value::Bool { val, .. } => {
|
||||
let v = <i64 as From<bool>>::from(*val);
|
||||
@ -244,22 +213,19 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value {
|
||||
for ch in bytes {
|
||||
raw_string.push_str(&format!("{:08b} ", ch));
|
||||
}
|
||||
Value::String {
|
||||
val: raw_string.trim().to_string(),
|
||||
span,
|
||||
}
|
||||
Value::string(raw_string.trim(), span)
|
||||
}
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => input.clone(),
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer, filesize, string, date, duration, binary or bool".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: span,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
},
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,50 +84,51 @@ impl Command for BitsNot {
|
||||
Example {
|
||||
description: "Apply logical negation to a list of numbers",
|
||||
example: "[4 3 2] | bits not",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_int(140737488355323),
|
||||
Value::test_int(140737488355324),
|
||||
Value::test_int(140737488355325),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description:
|
||||
"Apply logical negation to a list of numbers, treat input as 2 bytes number",
|
||||
example: "[4 3 2] | bits not -n '2'",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_int(65531),
|
||||
Value::test_int(65532),
|
||||
Value::test_int(65533),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description:
|
||||
"Apply logical negation to a list of numbers, treat input as signed number",
|
||||
example: "[4 3 2] | bits not -s",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_int(-5),
|
||||
Value::test_int(-4),
|
||||
Value::test_int(-3),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, head: Span, signed: bool, number_size: NumberBytes) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => {
|
||||
Value::Int { val, .. } => {
|
||||
if signed || val < 0 {
|
||||
Value::Int { val: !val, span }
|
||||
Value::int(!val, span)
|
||||
} else {
|
||||
use NumberBytes::*;
|
||||
let out_val = match number_size {
|
||||
@ -149,21 +150,21 @@ fn operate(value: Value, head: Span, signed: bool, number_size: NumberBytes) ->
|
||||
// This case shouldn't happen here, as it's handled before
|
||||
Invalid => 0,
|
||||
};
|
||||
Value::Int { val: out_val, span }
|
||||
Value::int(out_val, span)
|
||||
}
|
||||
}
|
||||
other => match other {
|
||||
// Propagate errors inside the value
|
||||
Value::Error { .. } => other,
|
||||
_ => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
_ => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -68,32 +68,30 @@ impl Command for BitsOr {
|
||||
Example {
|
||||
description: "Apply logical or to a list of numbers",
|
||||
example: "[8 3 2] | bits or 2",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(10), Value::test_int(3), Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_int(10), Value::test_int(3), Value::test_int(2)],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, target: i64, head: Span) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => Value::Int {
|
||||
val: val | target,
|
||||
span,
|
||||
},
|
||||
Value::Int { val, .. } => Value::int(val | target, span),
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,10 +91,10 @@ impl Command for BitsRol {
|
||||
Example {
|
||||
description: "Rotate left a list of numbers with 2 bits",
|
||||
example: "[5 3 2] | bits rol 2",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -106,9 +106,9 @@ where
|
||||
{
|
||||
let rotate_result = i64::try_from(val.rotate_left(bits));
|
||||
match rotate_result {
|
||||
Ok(val) => Value::Int { val, span },
|
||||
Err(_) => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
Ok(val) => Value::int(val, span),
|
||||
Err(_) => Value::error(
|
||||
ShellError::GenericError(
|
||||
"Rotate left result beyond the range of 64 bit signed number".to_string(),
|
||||
format!(
|
||||
"{val} of the specified number of bytes rotate left {bits} bits exceed limit"
|
||||
@ -116,15 +116,16 @@ where
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
),
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => {
|
||||
Value::Int { val, .. } => {
|
||||
use InputNumType::*;
|
||||
// let bits = (((bits % 64) + 64) % 64) as u32;
|
||||
let bits = bits as u32;
|
||||
@ -142,15 +143,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
||||
}
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,14 +91,14 @@ impl Command for BitsRor {
|
||||
Example {
|
||||
description: "Rotate right a list of numbers of one byte",
|
||||
example: "[15 33 92] | bits ror 2 -n '1'",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_int(195),
|
||||
Value::test_int(72),
|
||||
Value::test_int(23),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -110,9 +110,9 @@ where
|
||||
{
|
||||
let rotate_result = i64::try_from(val.rotate_right(bits));
|
||||
match rotate_result {
|
||||
Ok(val) => Value::Int { val, span },
|
||||
Err(_) => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
Ok(val) => Value::int(val, span),
|
||||
Err(_) => Value::error(
|
||||
ShellError::GenericError(
|
||||
"Rotate right result beyond the range of 64 bit signed number".to_string(),
|
||||
format!(
|
||||
"{val} of the specified number of bytes rotate right {bits} bits exceed limit"
|
||||
@ -120,15 +120,16 @@ where
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
),
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => {
|
||||
Value::Int { val, .. } => {
|
||||
use InputNumType::*;
|
||||
// let bits = (((bits % 64) + 64) % 64) as u32;
|
||||
let bits = bits as u32;
|
||||
@ -146,15 +147,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
||||
}
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,10 +101,10 @@ impl Command for BitsShl {
|
||||
Example {
|
||||
description: "Shift left a list of numbers",
|
||||
example: "[5 3 2] | bits shl 2",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -118,9 +118,9 @@ where
|
||||
Some(val) => {
|
||||
let shift_result = i64::try_from(val);
|
||||
match shift_result {
|
||||
Ok(val) => Value::Int { val, span },
|
||||
Err(_) => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
Ok(val) => Value::int( val, span ),
|
||||
Err(_) => Value::error(
|
||||
ShellError::GenericError(
|
||||
"Shift left result beyond the range of 64 bit signed number".to_string(),
|
||||
format!(
|
||||
"{val} of the specified number of bytes shift left {bits} bits exceed limit"
|
||||
@ -128,27 +128,28 @@ where
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
),
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
None => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
None => Value::error(
|
||||
ShellError::GenericError(
|
||||
"Shift left failed".to_string(),
|
||||
format!("{val} shift left {bits} bits failed, you may shift too many bits"),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
),
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => {
|
||||
Value::Int { val, .. } => {
|
||||
use InputNumType::*;
|
||||
// let bits = (((bits % 64) + 64) % 64) as u32;
|
||||
let bits = bits as u32;
|
||||
@ -166,15 +167,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
||||
}
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,10 +91,10 @@ impl Command for BitsShr {
|
||||
Example {
|
||||
description: "Shift right a list of numbers",
|
||||
example: "[15 35 2] | bits shr 2",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(3), Value::test_int(8), Value::test_int(0)],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_int(3), Value::test_int(8), Value::test_int(0)],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -108,9 +108,9 @@ where
|
||||
Some(val) => {
|
||||
let shift_result = i64::try_from(val);
|
||||
match shift_result {
|
||||
Ok(val) => Value::Int { val, span },
|
||||
Err(_) => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
Ok(val) => Value::int( val, span ),
|
||||
Err(_) => Value::error(
|
||||
ShellError::GenericError(
|
||||
"Shift right result beyond the range of 64 bit signed number".to_string(),
|
||||
format!(
|
||||
"{val} of the specified number of bytes shift right {bits} bits exceed limit"
|
||||
@ -118,27 +118,28 @@ where
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
),
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
None => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
None => Value::error(
|
||||
ShellError::GenericError(
|
||||
"Shift right failed".to_string(),
|
||||
format!("{val} shift right {bits} bits failed, you may shift too many bits"),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
),
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => {
|
||||
Value::Int { val, .. } => {
|
||||
use InputNumType::*;
|
||||
// let bits = (((bits % 64) + 64) % 64) as u32;
|
||||
let bits = bits as u32;
|
||||
@ -156,15 +157,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num
|
||||
}
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,32 +67,30 @@ impl Command for BitsXor {
|
||||
Example {
|
||||
description: "Apply logical xor to a list of numbers",
|
||||
example: "[8 3 2] | bits xor 2",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(10), Value::test_int(1), Value::test_int(0)],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_int(10), Value::test_int(1), Value::test_int(0)],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(value: Value, target: i64, head: Span) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Int { val, span } => Value::Int {
|
||||
val: val ^ target,
|
||||
span,
|
||||
},
|
||||
Value::Int { val, .. } => Value::int(val ^ target, span),
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "integer".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,15 +86,15 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
|
||||
Value::Filesize { val, .. } => fmt_it(*val, span),
|
||||
// Propagate errors by explicitly matching them before the final case.
|
||||
Value::Error { .. } => input.clone(),
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "float , integer or filesize".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: span,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
},
|
||||
span,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,26 +50,20 @@ impl Command for EachWhile {
|
||||
Example {
|
||||
example: "[1 2 3 2 1] | each while {|e| if $e < 3 { $e * 2 } }",
|
||||
description: "Produces a list of each element before the 3, doubled",
|
||||
result: Some(Value::List {
|
||||
vals: stream_test_1,
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(stream_test_1, Span::test_data())),
|
||||
},
|
||||
Example {
|
||||
example: r#"[1 2 stop 3 4] | each while {|e| if $e != 'stop' { $"Output: ($e)" } }"#,
|
||||
description: "Output elements until reaching 'stop'",
|
||||
result: Some(Value::List {
|
||||
vals: stream_test_2,
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(stream_test_2, Span::test_data())),
|
||||
},
|
||||
Example {
|
||||
example: r#"[1 2 3] | enumerate | each while {|e| if $e.item < 2 { $"value ($e.item) at ($e.index)!"} }"#,
|
||||
description: "Iterate over each element, printing the matching value and its index",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_string("value 1 at 0!")],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_string("value 1 at 0!")],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ fn vertical_rotate_value(
|
||||
by: Option<usize>,
|
||||
direction: VerticalDirection,
|
||||
) -> Result<Value, ShellError> {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::List { mut vals, span } => {
|
||||
Value::List { mut vals, .. } => {
|
||||
let rotations = by.map(|n| n % vals.len()).unwrap_or(1);
|
||||
let values = vals.as_mut_slice();
|
||||
|
||||
@ -31,10 +32,7 @@ fn vertical_rotate_value(
|
||||
VerticalDirection::Down => values.rotate_right(rotations),
|
||||
}
|
||||
|
||||
Ok(Value::List {
|
||||
vals: values.to_owned(),
|
||||
span,
|
||||
})
|
||||
Ok(Value::list(values.to_owned(), span))
|
||||
}
|
||||
_ => Err(ShellError::TypeMismatch {
|
||||
err_message: "list".to_string(),
|
||||
@ -54,10 +52,10 @@ fn horizontal_rotate_value(
|
||||
cells_only: bool,
|
||||
direction: &HorizontalDirection,
|
||||
) -> Result<Value, ShellError> {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Record {
|
||||
val: mut record,
|
||||
span,
|
||||
val: mut record, ..
|
||||
} => {
|
||||
let rotations = by.map(|n| n % record.len()).unwrap_or(1);
|
||||
|
||||
@ -75,13 +73,13 @@ fn horizontal_rotate_value(
|
||||
|
||||
Ok(Value::record(record, span))
|
||||
}
|
||||
Value::List { vals, span } => {
|
||||
Value::List { vals, .. } => {
|
||||
let values = vals
|
||||
.into_iter()
|
||||
.map(|value| horizontal_rotate_value(value, by, cells_only, direction))
|
||||
.collect::<Result<Vec<Value>, ShellError>>()?;
|
||||
|
||||
Ok(Value::List { vals: values, span })
|
||||
Ok(Value::list(values, span))
|
||||
}
|
||||
_ => Err(ShellError::TypeMismatch {
|
||||
err_message: "record".to_string(),
|
||||
|
@ -36,16 +36,16 @@ impl Command for Roll {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(
|
||||
Ok(Value::string(
|
||||
get_full_help(
|
||||
&Roll.signature(),
|
||||
&Roll.examples(),
|
||||
engine_state,
|
||||
stack,
|
||||
self.is_parser_keyword(),
|
||||
),
|
||||
span: call.head,
|
||||
}
|
||||
call.head,
|
||||
)
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ impl Command for RollDown {
|
||||
vec![Example {
|
||||
description: "Rolls rows down of a table",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | roll down",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: columns.clone(),
|
||||
vals: vec![Value::test_int(5), Value::test_int(6)],
|
||||
@ -52,8 +52,8 @@ impl Command for RollDown {
|
||||
vals: vec![Value::test_int(3), Value::test_int(4)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
}]
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ impl Command for RollLeft {
|
||||
Example {
|
||||
description: "Rolls columns of a table to the left",
|
||||
example: "[[a b c]; [1 2 3] [4 5 6]] | roll left",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: rotated_columns.clone(),
|
||||
vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(1)],
|
||||
@ -70,14 +70,14 @@ impl Command for RollLeft {
|
||||
vals: vec![Value::test_int(5), Value::test_int(6), Value::test_int(4)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rolls columns to the left without changing column names",
|
||||
example: "[[a b c]; [1 2 3] [4 5 6]] | roll left --cells-only",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: columns.clone(),
|
||||
vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(1)],
|
||||
@ -87,8 +87,8 @@ impl Command for RollLeft {
|
||||
vals: vec![Value::test_int(5), Value::test_int(6), Value::test_int(4)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ impl Command for RollRight {
|
||||
Example {
|
||||
description: "Rolls columns to the right",
|
||||
example: "[[a b c]; [1 2 3] [4 5 6]] | roll right",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: rotated_columns.clone(),
|
||||
vals: vec![Value::test_int(3), Value::test_int(1), Value::test_int(2)],
|
||||
@ -70,14 +70,14 @@ impl Command for RollRight {
|
||||
vals: vec![Value::test_int(6), Value::test_int(4), Value::test_int(5)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rolls columns to the right with fixed headers",
|
||||
example: "[[a b c]; [1 2 3] [4 5 6]] | roll right --cells-only",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: columns.clone(),
|
||||
vals: vec![Value::test_int(3), Value::test_int(1), Value::test_int(2)],
|
||||
@ -87,8 +87,8 @@ impl Command for RollRight {
|
||||
vals: vec![Value::test_int(6), Value::test_int(4), Value::test_int(5)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ impl Command for RollUp {
|
||||
vec![Example {
|
||||
description: "Rolls rows up",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | roll up",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: columns.clone(),
|
||||
vals: vec![Value::test_int(3), Value::test_int(4)],
|
||||
@ -52,8 +52,8 @@ impl Command for RollUp {
|
||||
vals: vec![Value::test_int(1), Value::test_int(2)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
}]
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,7 @@ impl Command for Rotate {
|
||||
Example {
|
||||
description: "Rotate a record clockwise, producing a table (like `transpose` but with column order reversed)",
|
||||
example: "{a:1, b:2} | rotate",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["column0".to_string(), "column1".to_string()],
|
||||
vals: vec![Value::test_int(1), Value::test_string("a")],
|
||||
@ -49,14 +48,14 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_int(2), Value::test_string("b")],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate 2x3 table clockwise",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | rotate",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec![
|
||||
"column0".to_string(),
|
||||
@ -86,14 +85,14 @@ impl Command for Rotate {
|
||||
],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table clockwise and change columns names",
|
||||
example: "[[a b]; [1 2]] | rotate col_a col_b",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["col_a".to_string(), "col_b".to_string()],
|
||||
vals: vec![Value::test_int(1), Value::test_string("a")],
|
||||
@ -103,14 +102,14 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_int(2), Value::test_string("b")],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table counter clockwise",
|
||||
example: "[[a b]; [1 2]] | rotate --ccw",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["column0".to_string(), "column1".to_string()],
|
||||
vals: vec![Value::test_string("b"), Value::test_int(2)],
|
||||
@ -120,14 +119,14 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_string("a"), Value::test_int(1)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table counter-clockwise",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | rotate --ccw",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec![
|
||||
"column0".to_string(),
|
||||
@ -157,14 +156,14 @@ impl Command for Rotate {
|
||||
],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table counter-clockwise and change columns names",
|
||||
example: "[[a b]; [1 2]] | rotate --ccw col_a col_b",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["col_a".to_string(), "col_b".to_string()],
|
||||
vals: vec![Value::test_string("b"), Value::test_int(2)],
|
||||
@ -174,8 +173,8 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_string("a"), Value::test_int(1)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -213,6 +212,7 @@ pub fn rotate(
|
||||
|
||||
if !values.is_empty() {
|
||||
for val in values.into_iter() {
|
||||
let span = val.span();
|
||||
match val {
|
||||
Value::Record { val: record, .. } => {
|
||||
old_column_names = record.cols;
|
||||
@ -226,9 +226,9 @@ pub fn rotate(
|
||||
new_values.push(v);
|
||||
}
|
||||
}
|
||||
Value::String { val, span } => {
|
||||
Value::String { val, .. } => {
|
||||
not_a_record = true;
|
||||
new_values.push(Value::String { val, span })
|
||||
new_values.push(Value::string(val, span))
|
||||
}
|
||||
x => {
|
||||
not_a_record = true;
|
||||
@ -273,16 +273,16 @@ pub fn rotate(
|
||||
}
|
||||
|
||||
if not_a_record {
|
||||
return Ok(Value::List {
|
||||
vals: vec![Value::record(
|
||||
return Ok(Value::list(
|
||||
vec![Value::record(
|
||||
Record {
|
||||
cols: new_column_names,
|
||||
vals: new_values,
|
||||
},
|
||||
call.head,
|
||||
)],
|
||||
span: call.head,
|
||||
}
|
||||
call.head,
|
||||
)
|
||||
.into_pipeline_data()
|
||||
.set_metadata(metadata));
|
||||
}
|
||||
@ -332,12 +332,9 @@ pub fn rotate(
|
||||
))
|
||||
}
|
||||
|
||||
Ok(Value::List {
|
||||
vals: final_values,
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data()
|
||||
.set_metadata(metadata))
|
||||
Ok(Value::list(final_values, call.head)
|
||||
.into_pipeline_data()
|
||||
.set_metadata(metadata))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -51,8 +51,8 @@ impl Command for UpdateCells {
|
||||
$value
|
||||
}
|
||||
}"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec![
|
||||
"2021-04-16".into(),
|
||||
"2021-06-10".into(),
|
||||
@ -72,8 +72,8 @@ impl Command for UpdateCells {
|
||||
Value::test_string(""),
|
||||
],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Update the zero value cells to empty strings in 2 last columns.",
|
||||
@ -87,8 +87,8 @@ impl Command for UpdateCells {
|
||||
$value
|
||||
}
|
||||
}"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec![
|
||||
"2021-04-16".into(),
|
||||
"2021-06-10".into(),
|
||||
@ -108,8 +108,8 @@ impl Command for UpdateCells {
|
||||
Value::test_string(""),
|
||||
],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -191,8 +191,9 @@ impl Iterator for UpdateCellIterator {
|
||||
}
|
||||
}
|
||||
|
||||
let span = val.span();
|
||||
match val {
|
||||
Value::Record { val, span } => Some(Value::record(
|
||||
Value::Record { val, .. } => Some(Value::record(
|
||||
val.into_iter()
|
||||
.map(|(col, val)| match &self.columns {
|
||||
Some(cols) if !cols.contains(&col) => (col, val),
|
||||
@ -251,10 +252,7 @@ fn process_cell(
|
||||
redirect_stderr,
|
||||
) {
|
||||
Ok(pd) => pd.into_value(span),
|
||||
Err(e) => Value::Error {
|
||||
error: Box::new(e),
|
||||
span,
|
||||
},
|
||||
Err(e) => Value::error(e, span),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,13 +288,13 @@ fn to_html(
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
return Ok(Value::List {
|
||||
vals: result,
|
||||
span: head,
|
||||
}
|
||||
.into_pipeline_data_with_metadata(Box::new(PipelineMetadata {
|
||||
data_source: DataSource::HtmlThemes,
|
||||
})));
|
||||
return Ok(
|
||||
Value::list(result, head).into_pipeline_data_with_metadata(Box::new(
|
||||
PipelineMetadata {
|
||||
data_source: DataSource::HtmlThemes,
|
||||
},
|
||||
)),
|
||||
);
|
||||
} else {
|
||||
let theme_span = match &theme {
|
||||
Some(v) => v.span,
|
||||
@ -403,7 +403,8 @@ fn html_table(table: Vec<Value>, headers: Vec<String>, config: &Config) -> Strin
|
||||
output_string.push_str("</tr></thead><tbody>");
|
||||
|
||||
for row in table {
|
||||
if let Value::Record { span, .. } = row {
|
||||
let span = row.span();
|
||||
if let Value::Record { .. } = row {
|
||||
output_string.push_str("<tr>");
|
||||
for header in &headers {
|
||||
let data = row.get_data_by_key(header);
|
||||
|
@ -70,9 +70,10 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -80,29 +81,29 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
let val = val.acos();
|
||||
let val = if use_degrees { val.to_degrees() } else { val };
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
} else {
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"'arccos' undefined for values outside the closed interval [-1, 1].".into(),
|
||||
"value originates from here".into(),
|
||||
head,
|
||||
span,
|
||||
)),
|
||||
),
|
||||
span,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,38 +61,39 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if (1.0..).contains(&val) {
|
||||
let val = val.acosh();
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
} else {
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"'arccosh' undefined for values below 1.".into(),
|
||||
"value originates from here".into(),
|
||||
head,
|
||||
span,
|
||||
)),
|
||||
),
|
||||
span,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,10 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -81,29 +82,29 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
let val = val.asin();
|
||||
let val = if use_degrees { val.to_degrees() } else { val };
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
} else {
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"'arcsin' undefined for values outside the closed interval [-1, 1].".into(),
|
||||
"value originates from here".into(),
|
||||
head,
|
||||
span,
|
||||
)),
|
||||
),
|
||||
span,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,26 +61,27 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let val = val.asinh();
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,27 +71,28 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let val = val.atan();
|
||||
let val = if use_degrees { val.to_degrees() } else { val };
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,38 +61,39 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if (-1.0..=1.0).contains(&val) {
|
||||
let val = val.atanh();
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
} else {
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"'arctanh' undefined for values outside the open interval (-1, 1).".into(),
|
||||
"value originates from here".into(),
|
||||
head,
|
||||
span,
|
||||
)),
|
||||
span: head,
|
||||
}
|
||||
),
|
||||
head,
|
||||
)
|
||||
}
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,16 +60,16 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "Apply the cosine to a list of angles in degrees",
|
||||
example: "[0 90 180 270 360] | math cos -d",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_float(1f64),
|
||||
Value::test_float(0f64),
|
||||
Value::test_float(-1f64),
|
||||
Value::test_float(0f64),
|
||||
Value::test_float(1f64),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -78,29 +78,27 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let val = if use_degrees { val.to_radians() } else { val };
|
||||
|
||||
Value::Float {
|
||||
val: val.cos(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.cos(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,27 +62,26 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Value::Float {
|
||||
val: val.cosh(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.cosh(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,27 +68,25 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Value::Float {
|
||||
val: val.exp(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.exp(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,38 +61,39 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if val > 0.0 {
|
||||
let val = val.ln();
|
||||
|
||||
Value::Float { val, span }
|
||||
Value::float(val, span)
|
||||
} else {
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"'ln' undefined for values outside the open interval (0, Inf).".into(),
|
||||
"value originates from here".into(),
|
||||
head,
|
||||
span,
|
||||
)),
|
||||
),
|
||||
span,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,16 +60,16 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "Apply the sine to a list of angles in degrees",
|
||||
example: "[0 90 180 270 360] | math sin -d | math round --precision 4",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_float(0f64),
|
||||
Value::test_float(1f64),
|
||||
Value::test_float(0f64),
|
||||
Value::test_float(-1f64),
|
||||
Value::test_float(0f64),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -78,29 +78,27 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let val = if use_degrees { val.to_radians() } else { val };
|
||||
|
||||
Value::Float {
|
||||
val: val.sin(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.sin(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,27 +62,25 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Value::Float {
|
||||
val: val.sinh(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.sinh(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,14 +60,14 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "Apply the tangent to a list of angles in degrees",
|
||||
example: "[-45 0 45] | math tan -d",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_float(-1f64),
|
||||
Value::test_float(0f64),
|
||||
Value::test_float(1f64),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -76,29 +76,27 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span, use_degrees: bool) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let val = if use_degrees { val.to_radians() } else { val };
|
||||
|
||||
Value::Float {
|
||||
val: val.tan(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.tan(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,27 +61,25 @@ impl Command for SubCommand {
|
||||
fn operate(value: Value, head: Span) -> Value {
|
||||
match value {
|
||||
numeric @ (Value::Int { .. } | Value::Float { .. }) => {
|
||||
let span = numeric.span();
|
||||
let (val, span) = match numeric {
|
||||
Value::Int { val, span } => (val as f64, span),
|
||||
Value::Float { val, span } => (val, span),
|
||||
Value::Int { val, .. } => (val as f64, span),
|
||||
Value::Float { val, .. } => (val, span),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Value::Float {
|
||||
val: val.tanh(),
|
||||
span,
|
||||
}
|
||||
Value::float(val.tanh(), span)
|
||||
}
|
||||
Value::Error { .. } => value,
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
other => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "numeric".into(),
|
||||
wrong_type: other.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: other.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,10 +138,7 @@ fn operate(
|
||||
Box::new(move |old| action(old, fgs_hex, fge_hex, bgs_hex, bge_hex, head)),
|
||||
);
|
||||
if let Err(error) = r {
|
||||
return Value::Error {
|
||||
error: Box::new(error),
|
||||
span: head,
|
||||
};
|
||||
return Value::error(error, head);
|
||||
}
|
||||
}
|
||||
ret
|
||||
@ -159,20 +156,20 @@ fn action(
|
||||
bg_end: Option<Rgb>,
|
||||
command_span: Span,
|
||||
) -> Value {
|
||||
let span = input.span();
|
||||
match input {
|
||||
Value::String { val, span } => {
|
||||
let span = *span;
|
||||
Value::String { val, .. } => {
|
||||
match (fg_start, fg_end, bg_start, bg_end) {
|
||||
(None, None, None, None) => {
|
||||
// Error - no colors
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::MissingParameter {
|
||||
Value::error(
|
||||
ShellError::MissingParameter {
|
||||
param_name:
|
||||
"please supply foreground and/or background color parameters".into(),
|
||||
span: command_span,
|
||||
}),
|
||||
span: command_span,
|
||||
}
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
(None, None, None, Some(bg_end)) => {
|
||||
// Error - missing bg_start, so assume black
|
||||
@ -294,13 +291,13 @@ fn action(
|
||||
other => {
|
||||
let got = format!("value is {}, not string", other.get_type());
|
||||
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::TypeMismatch {
|
||||
Value::error(
|
||||
ShellError::TypeMismatch {
|
||||
err_message: got,
|
||||
span: other.span(),
|
||||
}),
|
||||
span: other.span(),
|
||||
}
|
||||
},
|
||||
other.span(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,32 +118,30 @@ fn process_each_path(
|
||||
for path in column_paths {
|
||||
let ret = value.update_cell_path(&path.members, Box::new(|v| process_value(v, text)));
|
||||
if let Err(error) = ret {
|
||||
return Value::Error {
|
||||
error: Box::new(error),
|
||||
span: command_span,
|
||||
};
|
||||
return Value::error(error, command_span);
|
||||
}
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
fn process_value(value: &Value, text: &Option<String>) -> Value {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::String { val, span } => {
|
||||
Value::String { val, .. } => {
|
||||
let text = text.as_deref().unwrap_or(val.as_str());
|
||||
let result = add_osc_link(text, val.as_str());
|
||||
Value::string(result, *span)
|
||||
Value::string(result, span)
|
||||
}
|
||||
other => {
|
||||
let got = format!("value is {}, not string", other.get_type());
|
||||
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::TypeMismatch {
|
||||
Value::error(
|
||||
ShellError::TypeMismatch {
|
||||
err_message: got,
|
||||
span: other.span(),
|
||||
}),
|
||||
span: other.span(),
|
||||
}
|
||||
},
|
||||
other.span(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,62 +107,60 @@ fn action(
|
||||
Value::Error { .. } => input.clone(),
|
||||
Value::Binary { val, .. } => match hex_config.action_type {
|
||||
ActionType::Encode => Value::string(hex_encode(val.as_ref()), command_span),
|
||||
ActionType::Decode => Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
ActionType::Decode => Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"Binary data can only be encoded".to_string(),
|
||||
"value originates from here".into(),
|
||||
command_span,
|
||||
// This line requires the Value::Error {} match above.
|
||||
input.span(),
|
||||
)),
|
||||
span: command_span,
|
||||
},
|
||||
),
|
||||
command_span,
|
||||
),
|
||||
},
|
||||
Value::String { val, .. } => {
|
||||
match hex_config.action_type {
|
||||
ActionType::Encode => Value::Error {
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
ActionType::Encode => Value::error(
|
||||
ShellError::UnsupportedInput(
|
||||
"String value can only be decoded".to_string(),
|
||||
"value originates from here".into(),
|
||||
command_span,
|
||||
// This line requires the Value::Error {} match above.
|
||||
input.span(),
|
||||
)),
|
||||
span: command_span,
|
||||
},
|
||||
),
|
||||
command_span,
|
||||
),
|
||||
|
||||
ActionType::Decode => match hex_decode(val.as_ref()) {
|
||||
Ok(decoded_value) => Value::binary(decoded_value, command_span),
|
||||
Err(HexDecodingError::InvalidLength(len)) => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
Err(HexDecodingError::InvalidLength(len)) => Value::error(ShellError::GenericError(
|
||||
"value could not be hex decoded".to_string(),
|
||||
format!("invalid hex input length: {len}. The length should be even"),
|
||||
Some(command_span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
span: command_span,
|
||||
},
|
||||
Err(HexDecodingError::InvalidDigit(index, digit)) => Value::Error {
|
||||
error: Box::new(ShellError::GenericError(
|
||||
),
|
||||
command_span,
|
||||
),
|
||||
Err(HexDecodingError::InvalidDigit(index, digit)) => Value::error(ShellError::GenericError(
|
||||
"value could not be hex decoded".to_string(),
|
||||
format!("invalid hex digit: '{digit}' at index {index}. Only 0-9, A-F, a-f are allowed in hex encoding"),
|
||||
Some(command_span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
span: command_span,
|
||||
},
|
||||
),
|
||||
command_span,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
other => Value::Error {
|
||||
error: Box::new(ShellError::TypeMismatch {
|
||||
other => Value::error(
|
||||
ShellError::TypeMismatch {
|
||||
err_message: format!("string or binary, not {}", other.get_type()),
|
||||
span: other.span(),
|
||||
}),
|
||||
span: other.span(),
|
||||
},
|
||||
},
|
||||
other.span(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,10 @@ impl Command for Format {
|
||||
Example {
|
||||
description: "Print elements from some columns of a table",
|
||||
example: "[[col1, col2]; [v1, v2] [v3, v4]] | format '{col2}'",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_string("v2"), Value::test_string("v4")],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_string("v2"), Value::test_string("v4")],
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "convert a column from a table to camelCase",
|
||||
example: r#"[[lang, gems]; [nu_test, 100]] | str camel-case lang"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["lang".to_string(), "gems".to_string()],
|
||||
vals: vec![Value::test_string("nuTest"), Value::test_int(100)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "convert a column from a table to kebab-case",
|
||||
example: r#"[[lang, gems]; [nuTest, 100]] | str kebab-case lang"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["lang".to_string(), "gems".to_string()],
|
||||
vals: vec![Value::test_string("nu-test"), Value::test_int(100)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -57,19 +57,16 @@ where
|
||||
{
|
||||
let case_operation = args.case_operation;
|
||||
match input {
|
||||
Value::String { val, .. } => Value::String {
|
||||
val: case_operation(val),
|
||||
span: head,
|
||||
},
|
||||
Value::String { val, .. } => Value::string(case_operation(val), head),
|
||||
Value::Error { .. } => input.clone(),
|
||||
_ => Value::Error {
|
||||
error: Box::new(ShellError::OnlySupportsThisInputType {
|
||||
_ => Value::error(
|
||||
ShellError::OnlySupportsThisInputType {
|
||||
exp_input_type: "string".into(),
|
||||
wrong_type: input.get_type().to_string(),
|
||||
dst_span: head,
|
||||
src_span: input.span(),
|
||||
}),
|
||||
span: head,
|
||||
},
|
||||
},
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "convert a column from a table to PascalCase",
|
||||
example: r#"[[lang, gems]; [nu_test, 100]] | str pascal-case lang"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["lang".to_string(), "gems".to_string()],
|
||||
vals: vec![Value::test_string("NuTest"), Value::test_int(100)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "convert a column from a table to SCREAMING_SNAKE_CASE",
|
||||
example: r#"[[lang, gems]; [nu_test, 100]] | str screaming-snake-case lang"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["lang".to_string(), "gems".to_string()],
|
||||
vals: vec![Value::test_string("NU_TEST"), Value::test_int(100)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "convert a column from a table to snake_case",
|
||||
example: r#"[[lang, gems]; [nuTest, 100]] | str snake-case lang"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["lang".to_string(), "gems".to_string()],
|
||||
vals: vec![Value::test_string("nu_test"), Value::test_int(100)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -34,16 +34,16 @@ impl Command for Str {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(
|
||||
Ok(Value::string(
|
||||
get_full_help(
|
||||
&Str.signature(),
|
||||
&Str.examples(),
|
||||
engine_state,
|
||||
stack,
|
||||
self.is_parser_keyword(),
|
||||
),
|
||||
span: call.head,
|
||||
}
|
||||
call.head,
|
||||
)
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "convert a column from a table to Title Case",
|
||||
example: r#"[[title, count]; ['nu test', 100]] | str title-case title"#,
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["title".to_string(), "count".to_string()],
|
||||
vals: vec![Value::test_string("Nu Test"), Value::test_int(100)],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user