diff --git a/crates/nu-cli/src/commands/str_/collect.rs b/crates/nu-cli/src/commands/str_/collect.rs index 091d55260c..bc68c22ed8 100644 --- a/crates/nu-cli/src/commands/str_/collect.rs +++ b/crates/nu-cli/src/commands/str_/collect.rs @@ -1,10 +1,16 @@ use crate::commands::WholeStreamCommand; use crate::prelude::*; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, UntaggedValue, Value}; +use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; +use nu_source::Tagged; pub struct SubCommand; +#[derive(Deserialize)] +pub struct SubCommandArgs { + separator: Option>, +} + #[async_trait] impl WholeStreamCommand for SubCommand { fn name(&self) -> &str { @@ -12,7 +18,11 @@ impl WholeStreamCommand for SubCommand { } fn signature(&self) -> Signature { - Signature::build("str collect") + Signature::build("str collect").desc(self.usage()).optional( + "separator", + SyntaxShape::String, + "the separator to put between the different values", + ) } fn usage(&self) -> &str { @@ -22,16 +32,9 @@ impl WholeStreamCommand for SubCommand { async fn run( &self, args: CommandArgs, - _registry: &CommandRegistry, + registry: &CommandRegistry, ) -> Result { - let output = args - .input - .collect_string(args.call_info.name_tag.clone()) - .await?; - - Ok(OutputStream::one(ReturnSuccess::value( - UntaggedValue::string(output.item).into_value(output.tag), - ))) + collect(args, registry).await } fn examples(&self) -> Vec { @@ -43,6 +46,24 @@ impl WholeStreamCommand for SubCommand { } } +pub async fn collect( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let tag = args.call_info.name_tag.clone(); + let (SubCommandArgs { separator }, input) = args.process(registry).await?; + let separator = separator.map(|tagged| tagged.item).unwrap_or_default(); + + let strings: Vec> = + input.map(|value| value.as_string()).collect().await; + let strings: Vec = strings.into_iter().collect::>()?; + let output = strings.join(&separator); + + Ok(OutputStream::one(ReturnSuccess::value( + UntaggedValue::string(output).into_value(tag), + ))) +} + #[cfg(test)] mod tests { use super::SubCommand; diff --git a/crates/nu-cli/tests/commands/str_/collect.rs b/crates/nu-cli/tests/commands/str_/collect.rs new file mode 100644 index 0000000000..7d39c70fe7 --- /dev/null +++ b/crates/nu-cli/tests/commands/str_/collect.rs @@ -0,0 +1,53 @@ +use nu_test_support::{nu, pipeline}; + +#[test] +fn test_1() { + let actual = nu!( + cwd: ".", pipeline( + r#" + echo 1..5 | str from | str collect + "# + ) + ); + + assert_eq!(actual.out, "12345"); +} + +#[test] +fn test_2() { + let actual = nu!( + cwd: ".", pipeline( + r#" + echo [a b c d] | str collect "" + "# + ) + ); + + assert_eq!(actual.out, "abcd"); +} + +#[test] +fn construct_a_path() { + let actual = nu!( + cwd: ".", pipeline( + r#" + echo [sample txt] | str collect "." + "# + ) + ); + + assert_eq!(actual.out, "sample.txt"); +} + +#[test] +fn sum_one_to_four() { + let actual = nu!( + cwd: ".", pipeline( + r#" + echo 1..4 | str from | str collect "+" | math eval + "# + ) + ); + + assert!(actual.out.contains("10.0")); +} diff --git a/crates/nu-cli/tests/commands/str_.rs b/crates/nu-cli/tests/commands/str_/mod.rs similarity index 99% rename from crates/nu-cli/tests/commands/str_.rs rename to crates/nu-cli/tests/commands/str_/mod.rs index eb3f25cdde..66e293fb3f 100644 --- a/crates/nu-cli/tests/commands/str_.rs +++ b/crates/nu-cli/tests/commands/str_/mod.rs @@ -1,3 +1,5 @@ +mod collect; + use nu_test_support::fs::Stub::FileWithContent; use nu_test_support::playground::Playground; use nu_test_support::{nu, pipeline};