From 8775991c2d11d832c4889c18a42342cdcbff9213 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Fri, 3 Jul 2020 12:09:38 -0700 Subject: [PATCH] Add 'split chars' command (#2101) --- crates/nu-cli/src/cli.rs | 1 + crates/nu-cli/src/commands.rs | 1 + crates/nu-cli/src/commands/split/chars.rs | 84 +++++++++++++++++++++++ crates/nu-cli/src/commands/split/mod.rs | 2 + 4 files changed, 88 insertions(+) create mode 100644 crates/nu-cli/src/commands/split/chars.rs diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 9ad236173b..f9e195d874 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -288,6 +288,7 @@ pub fn create_default_context( whole_stream_command(Split), whole_stream_command(SplitColumn), whole_stream_command(SplitRow), + whole_stream_command(SplitChars), whole_stream_command(Lines), whole_stream_command(Trim), whole_stream_command(Echo), diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index d0b7b09528..7ea0720102 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -238,6 +238,7 @@ pub(crate) use skip_until::SkipUntil; pub(crate) use skip_while::SkipWhile; pub(crate) use sort_by::SortBy; pub(crate) use split::Split; +pub(crate) use split::SplitChars; pub(crate) use split::SplitColumn; pub(crate) use split::SplitRow; pub(crate) use split_by::SplitBy; diff --git a/crates/nu-cli/src/commands/split/chars.rs b/crates/nu-cli/src/commands/split/chars.rs new file mode 100644 index 0000000000..1feae2934f --- /dev/null +++ b/crates/nu-cli/src/commands/split/chars.rs @@ -0,0 +1,84 @@ +use crate::commands::WholeStreamCommand; +use crate::prelude::*; +use nu_errors::ShellError; +use nu_protocol::{ReturnSuccess, Signature, Value}; + +pub struct SubCommand; + +#[async_trait] +impl WholeStreamCommand for SubCommand { + fn name(&self) -> &str { + "split chars" + } + + fn signature(&self) -> Signature { + Signature::build("split chars") + } + + fn usage(&self) -> &str { + "splits a string's characters into separate rows" + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + split_chars(args, registry).await + } + + fn examples(&self) -> Vec { + vec![Example { + description: "Split the string's characters into separate rows", + example: "echo 'hello' | split chars", + result: Some(vec![ + Value::from("h"), + Value::from("e"), + Value::from("l"), + Value::from("l"), + Value::from("o"), + ]), + }] + } +} + +async fn split_chars( + args: CommandArgs, + _registry: &CommandRegistry, +) -> Result { + let name = args.call_info.name_tag.clone(); + let input = args.input; + Ok(input + .flat_map(move |v| { + if let Ok(s) = v.as_string() { + futures::stream::iter( + s.chars() + .collect::>() + .into_iter() + .map(move |x| ReturnSuccess::value(Value::from(x.to_string()))), + ) + .to_output_stream() + } else { + OutputStream::one(Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", + name.span, + "value originates from here", + v.tag.span, + ))) + } + }) + .to_output_stream()) +} + +#[cfg(test)] +mod tests { + use super::SubCommand; + + #[test] + fn examples_work_as_expected() { + use crate::examples::test as test_examples; + + test_examples(SubCommand {}) + } +} diff --git a/crates/nu-cli/src/commands/split/mod.rs b/crates/nu-cli/src/commands/split/mod.rs index 4c5e83026c..18bc0717ac 100644 --- a/crates/nu-cli/src/commands/split/mod.rs +++ b/crates/nu-cli/src/commands/split/mod.rs @@ -1,7 +1,9 @@ +pub mod chars; pub mod column; pub mod command; pub mod row; +pub use chars::SubCommand as SplitChars; pub use column::SubCommand as SplitColumn; pub use command::Command as Split; pub use row::SubCommand as SplitRow;