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:
JT
2023-09-04 02:27:29 +12:00
committed by GitHub
parent af79eb2943
commit 6cdfee3573
372 changed files with 5811 additions and 7448 deletions

View File

@ -46,28 +46,28 @@ impl Command for SubCommand {
Example {
description: "Split the string into a list of characters",
example: "'hello' | split chars",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string("h"),
Value::test_string("e"),
Value::test_string("l"),
Value::test_string("l"),
Value::test_string("o"),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split on grapheme clusters",
example: "'🇯🇵ほげ' | split chars -g",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string("🇯🇵"),
Value::test_string(""),
Value::test_string(""),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split multiple strings into lists of characters",
@ -118,16 +118,14 @@ fn split_chars(
}
fn split_chars_helper(v: &Value, name: Span, graphemes: bool) -> Value {
let span = v.span();
match v {
Value::Error { error, span } => Value::Error {
error: error.clone(),
span: *span,
},
Value::Error { error, .. } => Value::error(*error.clone(), span),
v => {
let v_span = v.span();
if let Ok(s) = v.as_string() {
Value::List {
vals: if graphemes {
Value::list(
if graphemes {
s.graphemes(true)
.collect::<Vec<_>>()
.into_iter()
@ -140,17 +138,17 @@ fn split_chars_helper(v: &Value, name: Span, graphemes: bool) -> Value {
.map(move |x| Value::string(x, v_span))
.collect()
},
span: v_span,
}
v_span,
)
} else {
Value::Error {
error: Box::new(ShellError::PipelineMismatch {
Value::error(
ShellError::PipelineMismatch {
exp_input_type: "string".into(),
dst_span: name,
src_span: v_span,
}),
span: name,
}
},
name,
)
}
}
}

View File

@ -63,8 +63,8 @@ impl Command for SubCommand {
Example {
description: "Split a string into columns by the specified separator",
example: "'a--b--c' | split column '--'",
result: Some(Value::List {
vals: vec![Value::test_record(Record {
result: Some(Value::list(
vec![Value::test_record(Record {
cols: vec![
"column1".to_string(),
"column2".to_string(),
@ -76,14 +76,14 @@ impl Command for SubCommand {
Value::test_string("c"),
],
})],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a string into columns of char and remove the empty columns",
example: "'abc' | split column -c ''",
result: Some(Value::List {
vals: vec![Value::test_record(Record {
result: Some(Value::list(
vec![Value::test_record(Record {
cols: vec![
"column1".to_string(),
"column2".to_string(),
@ -95,14 +95,14 @@ impl Command for SubCommand {
Value::test_string("c"),
],
})],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a list of strings into a table",
example: "['a-b' 'c-d'] | split column -",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_record(Record {
cols: vec!["column1".to_string(), "column2".to_string()],
vals: vec![Value::test_string("a"), Value::test_string("b")],
@ -112,14 +112,14 @@ impl Command for SubCommand {
vals: vec![Value::test_string("c"), Value::test_string("d")],
}),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a list of strings into a table, ignoring padding",
example: r"['a - b' 'c - d'] | split column -r '\s*-\s*'",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_record(Record {
cols: vec!["column1".to_string(), "column2".to_string()],
vals: vec![Value::test_string("a"), Value::test_string("b")],
@ -129,8 +129,8 @@ impl Command for SubCommand {
vals: vec![Value::test_string("c"), Value::test_string("d")],
}),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
]
}
@ -203,21 +203,18 @@ fn split_column_helper(
} else {
match v {
Value::Error { error, .. } => {
vec![Value::Error {
error: Box::new(*error.clone()),
span: head,
}]
vec![Value::error(*error.clone(), head)]
}
v => {
let span = v.span();
vec![Value::Error {
error: Box::new(ShellError::PipelineMismatch {
vec![Value::error(
ShellError::PipelineMismatch {
exp_input_type: "string".into(),
dst_span: head,
src_span: span,
}),
},
span,
}]
)]
}
}
}

View File

@ -34,16 +34,16 @@ impl Command for SplitCommand {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(Value::String {
val: get_full_help(
Ok(Value::string(
get_full_help(
&SplitCommand.signature(),
&SplitCommand.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
call.head,
)
.into_pipeline_data())
}
}

View File

@ -56,100 +56,97 @@ impl Command for SubCommand {
Example {
description: "Split a list of chars into two lists",
example: "[a, b, c, d, e, f, g] | split list d",
result: Some(Value::List {
vals: vec![
Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::list(
vec![
Value::test_string("a"),
Value::test_string("b"),
Value::test_string("c"),
],
span: Span::test_data(),
},
Value::List {
vals: vec![
Span::test_data(),
),
Value::list(
vec![
Value::test_string("e"),
Value::test_string("f"),
Value::test_string("g"),
],
span: Span::test_data(),
},
Span::test_data(),
),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a list of lists into two lists of lists",
example: "[[1,2], [2,3], [3,4]] | split list [2,3]",
result: Some(Value::List {
vals: vec![
Value::List {
vals: vec![Value::List {
vals: vec![Value::test_int(1), Value::test_int(2)],
span: Span::test_data(),
}],
span: Span::test_data(),
},
Value::List {
vals: vec![Value::List {
vals: vec![Value::test_int(3), Value::test_int(4)],
span: Span::test_data(),
}],
span: Span::test_data(),
},
result: Some(Value::list(
vec![
Value::list(
vec![Value::list(
vec![Value::test_int(1), Value::test_int(2)],
Span::test_data(),
)],
Span::test_data(),
),
Value::list(
vec![Value::list(
vec![Value::test_int(3), Value::test_int(4)],
Span::test_data(),
)],
Span::test_data(),
),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a list of chars into two lists",
example: "[a, b, c, d, a, e, f, g] | split list a",
result: Some(Value::List {
vals: vec![
Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::list(
vec![
Value::test_string("b"),
Value::test_string("c"),
Value::test_string("d"),
],
span: Span::test_data(),
},
Value::List {
vals: vec![
Span::test_data(),
),
Value::list(
vec![
Value::test_string("e"),
Value::test_string("f"),
Value::test_string("g"),
],
span: Span::test_data(),
},
Span::test_data(),
),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a list of chars into lists based on multiple characters",
example: r"[a, b, c, d, a, e, f, g] | split list -r '(b|e)'",
result: Some(Value::List {
vals: vec![
Value::List {
vals: vec![Value::test_string("a")],
span: Span::test_data(),
},
Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::list(vec![Value::test_string("a")], Span::test_data()),
Value::list(
vec![
Value::test_string("c"),
Value::test_string("d"),
Value::test_string("a"),
],
span: Span::test_data(),
},
Value::List {
vals: vec![Value::test_string("f"), Value::test_string("g")],
span: Span::test_data(),
},
Span::test_data(),
),
Value::list(
vec![Value::test_string("f"), Value::test_string("g")],
Span::test_data(),
),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
]
}
@ -211,10 +208,7 @@ fn split_list(
for val in iter {
if matcher.compare(&val)? {
if !temp_list.is_empty() {
returned_list.push(Value::List {
vals: temp_list.clone(),
span: call.head,
});
returned_list.push(Value::list(temp_list.clone(), call.head));
temp_list = Vec::new();
}
} else {
@ -222,16 +216,9 @@ fn split_list(
}
}
if !temp_list.is_empty() {
returned_list.push(Value::List {
vals: temp_list.clone(),
span: call.head,
});
returned_list.push(Value::list(temp_list.clone(), call.head));
}
Ok(Value::List {
vals: returned_list,
span: call.head,
}
.into_pipeline_data())
Ok(Value::list(returned_list, call.head).into_pipeline_data())
}
#[cfg(test)]

View File

@ -62,54 +62,54 @@ impl Command for SubCommand {
Example {
description: "Split a string into rows of char",
example: "'abc' | split row ''",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string(""),
Value::test_string("a"),
Value::test_string("b"),
Value::test_string("c"),
Value::test_string(""),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a string into rows by the specified separator",
example: "'a--b--c' | split row '--'",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string("a"),
Value::test_string("b"),
Value::test_string("c"),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a string by '-'",
example: "'-a-b-c-' | split row '-'",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string(""),
Value::test_string("a"),
Value::test_string("b"),
Value::test_string("c"),
Value::test_string(""),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description: "Split a string by regex",
example: r"'a b c' | split row -r '\s+'",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string("a"),
Value::test_string("b"),
Value::test_string("c"),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
]
}
@ -146,12 +146,10 @@ fn split_row(
}
fn split_row_helper(v: &Value, regex: &Regex, max_split: Option<usize>, name: Span) -> Vec<Value> {
let span = v.span();
match v {
Value::Error { error, span } => {
vec![Value::Error {
error: Box::new(*error.clone()),
span: *span,
}]
Value::Error { error, .. } => {
vec![Value::error(*error.clone(), span)]
}
v => {
let v_span = v.span();
@ -168,14 +166,14 @@ fn split_row_helper(v: &Value, regex: &Regex, max_split: Option<usize>, name: Sp
.collect(),
}
} else {
vec![Value::Error {
error: Box::new(ShellError::PipelineMismatch {
vec![Value::error(
ShellError::PipelineMismatch {
exp_input_type: "string".into(),
dst_span: name,
src_span: v_span,
}),
span: name,
}]
},
name,
)]
}
}
}

View File

@ -73,23 +73,23 @@ impl Command for SubCommand {
Example {
description: "Split the string's words into separate rows",
example: "'hello world' | split words",
result: Some(Value::List {
vals: vec![Value::test_string("hello"), Value::test_string("world")],
span: Span::test_data(),
}),
result: Some(Value::list(
vec![Value::test_string("hello"), Value::test_string("world")],
Span::test_data(),
)),
},
Example {
description:
"Split the string's words, of at least 3 characters, into separate rows",
example: "'hello to the world' | split words -l 3",
result: Some(Value::List {
vals: vec![
result: Some(Value::list(
vec![
Value::test_string("hello"),
Value::test_string("the"),
Value::test_string("world"),
],
span: Span::test_data(),
}),
Span::test_data(),
)),
},
Example {
description:
@ -152,12 +152,10 @@ fn split_words_helper(v: &Value, word_length: Option<usize>, span: Span, graphem
// [^\p{L}\'] = do not match any unicode uppercase or lowercase letters or apostrophes
// Let's go with the unicode one in hopes that it works on more than just ascii characters
let regex_replace = Regex::new(r"[^\p{L}\']").expect("regular expression error");
let v_span = v.span();
match v {
Value::Error { error, span } => Value::Error {
error: Box::new(*error.clone()),
span: *span,
},
Value::Error { error, .. } => Value::error(*error.clone(), v_span),
v => {
let v_span = v.span();
if let Ok(s) = v.as_string() {
@ -189,19 +187,16 @@ fn split_words_helper(v: &Value, word_length: Option<usize>, span: Span, graphem
}
})
.collect::<Vec<Value>>();
Value::List {
vals: words,
span: v_span,
}
Value::list(words, v_span)
} else {
Value::Error {
error: Box::new(ShellError::PipelineMismatch {
Value::error(
ShellError::PipelineMismatch {
exp_input_type: "string".into(),
dst_span: span,
src_span: v_span,
}),
span,
}
},
v_span,
)
}
}
}