forked from extern/nushell
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:
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}]
|
||||
)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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,
|
||||
)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user