diff --git a/src/cli.rs b/src/cli.rs index 9661cb3202..f46db10529 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -264,6 +264,8 @@ pub async fn cli() -> Result<(), Box> { whole_stream_command(Lines), whole_stream_command(Reject), whole_stream_command(Reverse), + whole_stream_command(Append), + whole_stream_command(Prepend), whole_stream_command(Trim), whole_stream_command(ToBSON), whole_stream_command(ToCSV), diff --git a/src/commands.rs b/src/commands.rs index c75ca81192..ba69d1e822 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,6 +1,7 @@ #[macro_use] pub(crate) mod macros; +pub(crate) mod append; pub(crate) mod args; pub(crate) mod autoview; pub(crate) mod cd; @@ -45,6 +46,7 @@ pub(crate) mod pick; pub(crate) mod pivot; pub(crate) mod plugin; pub(crate) mod post; +pub(crate) mod prepend; pub(crate) mod prev; pub(crate) mod pwd; pub(crate) mod reject; @@ -79,6 +81,7 @@ pub(crate) use command::{ UnevaluatedCallInfo, WholeStreamCommand, }; +pub(crate) use append::Append; pub(crate) use classified::ClassifiedCommand; pub(crate) use config::Config; pub(crate) use count::Count; @@ -119,6 +122,7 @@ pub(crate) use open::Open; pub(crate) use pick::Pick; pub(crate) use pivot::Pivot; pub(crate) use post::Post; +pub(crate) use prepend::Prepend; pub(crate) use prev::Previous; pub(crate) use pwd::PWD; pub(crate) use reject::Reject; diff --git a/src/commands/append.rs b/src/commands/append.rs new file mode 100644 index 0000000000..fe22c9065e --- /dev/null +++ b/src/commands/append.rs @@ -0,0 +1,47 @@ +use crate::commands::WholeStreamCommand; +use crate::errors::ShellError; +use crate::parser::CommandRegistry; +use crate::prelude::*; + +#[derive(Deserialize)] +struct AppendArgs { + row: Tagged, +} + +pub struct Append; + +impl WholeStreamCommand for Append { + fn name(&self) -> &str { + "append" + } + + fn signature(&self) -> Signature { + Signature::build("append").required( + "row value", + SyntaxShape::Any, + "the value of the row to append to the table", + ) + } + + fn usage(&self) -> &str { + "Append the given row to the table" + } + + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + args.process(registry, append)?.run() + } +} + +fn append( + AppendArgs { row }: AppendArgs, + RunnableContext { input, .. }: RunnableContext, +) -> Result { + let mut after: VecDeque> = VecDeque::new(); + after.push_back(row); + + Ok(OutputStream::from_input(input.values.chain(after))) +} diff --git a/src/commands/prepend.rs b/src/commands/prepend.rs new file mode 100644 index 0000000000..b6fa935b0b --- /dev/null +++ b/src/commands/prepend.rs @@ -0,0 +1,47 @@ +use crate::commands::WholeStreamCommand; +use crate::errors::ShellError; +use crate::parser::CommandRegistry; +use crate::prelude::*; + +#[derive(Deserialize)] +struct PrependArgs { + row: Tagged, +} + +pub struct Prepend; + +impl WholeStreamCommand for Prepend { + fn name(&self) -> &str { + "prepend" + } + + fn signature(&self) -> Signature { + Signature::build("prepend").required( + "row value", + SyntaxShape::Any, + "the value of the row to prepend to the table", + ) + } + + fn usage(&self) -> &str { + "Prepend the given row to the front of the table" + } + + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + args.process(registry, prepend)?.run() + } +} + +fn prepend( + PrependArgs { row }: PrependArgs, + RunnableContext { input, .. }: RunnableContext, +) -> Result { + let mut prepend: VecDeque> = VecDeque::new(); + prepend.push_back(row); + + Ok(OutputStream::from_input(prepend.chain(input.values))) +} diff --git a/tests/tests.rs b/tests/tests.rs index 1a739f1982..14552a41ee 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -72,6 +72,38 @@ fn read_plugin() { assert_eq!(actual, "StupidLongName"); } +#[test] +fn prepend_plugin() { + let actual = nu!( + cwd: "tests/fixtures/formats", h::pipeline( + r#" + open fileA.txt + | lines + | prepend "testme" + | nth 0 + | echo $it + "# + )); + + assert_eq!(actual, "testme"); +} + +#[test] +fn append_plugin() { + let actual = nu!( + cwd: "tests/fixtures/formats", h::pipeline( + r#" + open fileA.txt + | lines + | append "testme" + | nth 3 + | echo $it + "# + )); + + assert_eq!(actual, "testme"); +} + #[test] fn edit_plugin() { let actual = nu!(