diff --git a/Cargo.lock b/Cargo.lock index 5327b83c..c73d0d0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -695,6 +695,7 @@ dependencies = [ "nu-protocol", "nu-table", "nu-term-grid", + "rand", "rayon", "sysinfo", "terminal_size", diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index ee1470a8..1326ec75 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -32,6 +32,7 @@ dialoguer = "0.9.0" rayon = "1.5.1" titlecase = "1.1.0" meval = "0.2.0" +rand = "0.8" [features] trash-support = ["trash"] diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index bd84acaf..a5946fb1 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -88,6 +88,7 @@ pub fn create_default_context() -> EngineState { Range, Rm, Select, + Shuffle, Size, ScreamingSnakeCase, SnakeCase, diff --git a/crates/nu-command/src/filters/mod.rs b/crates/nu-command/src/filters/mod.rs index ff1af74c..0adfe112 100644 --- a/crates/nu-command/src/filters/mod.rs +++ b/crates/nu-command/src/filters/mod.rs @@ -7,6 +7,7 @@ mod lines; mod par_each; mod range; mod select; +mod shuffle; mod where_; mod wrap; mod zip; @@ -20,6 +21,7 @@ pub use lines::Lines; pub use par_each::ParEach; pub use range::Range; pub use select::Select; +pub use shuffle::Shuffle; pub use where_::Where; pub use wrap::Wrap; pub use zip::Zip; diff --git a/crates/nu-command/src/filters/shuffle.rs b/crates/nu-command/src/filters/shuffle.rs new file mode 100644 index 00000000..f9e3dd75 --- /dev/null +++ b/crates/nu-command/src/filters/shuffle.rs @@ -0,0 +1,35 @@ +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{IntoInterruptiblePipelineData, PipelineData, ShellError, Signature}; +use rand::prelude::SliceRandom; +use rand::thread_rng; + +#[derive(Clone)] +pub struct Shuffle; + +impl Command for Shuffle { + fn name(&self) -> &str { + "shuffle" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("shuffle") + } + + fn usage(&self) -> &str { + "Shuffle rows randomly." + } + + fn run( + &self, + engine_state: &EngineState, + _stack: &mut Stack, + _call: &Call, + input: PipelineData, + ) -> Result { + let mut v: Vec<_> = input.into_iter().collect(); + v.shuffle(&mut thread_rng()); + let iter = v.into_iter(); + Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) + } +}