From 1ffbb66e64adab575ab9b611d0083f6797da144e Mon Sep 17 00:00:00 2001 From: smaydew <65190294+smaydew@users.noreply.github.com> Date: Thu, 3 Sep 2020 13:23:02 -0600 Subject: [PATCH] Initial implementation of random integer subcommand. (#2489) * Initial implementation of random integer subcommand. * Added additional examples. Co-authored-by: Stacy Maydew --- crates/nu-cli/src/cli.rs | 1 + crates/nu-cli/src/commands.rs | 2 +- crates/nu-cli/src/commands/random/integer.rs | 102 ++++++++++++++++++ crates/nu-cli/src/commands/random/mod.rs | 2 + .../nu-cli/tests/commands/random/integer.rs | 13 +++ crates/nu-cli/tests/commands/random/mod.rs | 1 + docs/commands/random.md | 31 ++++++ 7 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 crates/nu-cli/src/commands/random/integer.rs create mode 100644 crates/nu-cli/tests/commands/random/integer.rs diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 16cd1e7a22..e51709158d 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -265,6 +265,7 @@ pub fn create_default_context( whole_stream_command(RandomDice), #[cfg(feature = "uuid_crate")] whole_stream_command(RandomUUID), + whole_stream_command(RandomInteger), // Path whole_stream_command(PathBasename), whole_stream_command(PathCommand), diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index 96d3c8acf0..f0e61e78cd 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -218,7 +218,7 @@ pub(crate) use prev::Previous; pub(crate) use pwd::Pwd; #[cfg(feature = "uuid_crate")] pub(crate) use random::RandomUUID; -pub(crate) use random::{Random, RandomBool, RandomDice}; +pub(crate) use random::{Random, RandomBool, RandomDice, RandomInteger}; pub(crate) use range::Range; pub(crate) use reduce::Reduce; pub(crate) use reject::Reject; diff --git a/crates/nu-cli/src/commands/random/integer.rs b/crates/nu-cli/src/commands/random/integer.rs new file mode 100644 index 0000000000..2ddb6c1c42 --- /dev/null +++ b/crates/nu-cli/src/commands/random/integer.rs @@ -0,0 +1,102 @@ +use crate::commands::WholeStreamCommand; +use crate::prelude::*; +use nu_errors::ShellError; +use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue}; +use nu_source::Tagged; +use rand::prelude::{thread_rng, Rng}; + +pub struct SubCommand; + +#[derive(Deserialize)] +pub struct IntegerArgs { + min: Option>, + max: Option>, +} + +#[async_trait] +impl WholeStreamCommand for SubCommand { + fn name(&self) -> &str { + "random integer" + } + + fn signature(&self) -> Signature { + Signature::build("random integer") + .named("min", SyntaxShape::Int, "Minimum value", Some('m')) + .named("max", SyntaxShape::Int, "Maximum value", Some('x')) + } + + fn usage(&self) -> &str { + "Generate a random integer [--min ] [--max ]" + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + integer(args, registry).await + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Generate an unconstrained random integer", + example: "random integer", + result: None, + }, + Example { + description: "Generate a random integer less than or equal to 500", + example: "random integer --max 500", + result: None, + }, + Example { + description: "Generate a random integer greater than or equal to 100000", + example: "random integer --min 100000", + result: None, + }, + Example { + description: "Generate a random integer between 1 and 10", + example: "random integer --min 1 --max 10", + result: None, + }, + ] + } +} + +pub async fn integer( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let (IntegerArgs { min, max }, _) = args.process(®istry).await?; + + let min = if let Some(min_tagged) = min { + *min_tagged + } else { + 0 + }; + + let max = if let Some(max_tagged) = max { + *max_tagged + } else { + u64::MAX + }; + + let mut thread_rng = thread_rng(); + let result: u64 = thread_rng.gen_range(min, max); + + let untagged_result = UntaggedValue::int(result).into_value(Tag::unknown()); + + Ok(OutputStream::one(ReturnSuccess::value(untagged_result))) +} + +#[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/random/mod.rs b/crates/nu-cli/src/commands/random/mod.rs index 0dbacfd80d..3cd4d14eb9 100644 --- a/crates/nu-cli/src/commands/random/mod.rs +++ b/crates/nu-cli/src/commands/random/mod.rs @@ -2,6 +2,7 @@ pub mod command; pub mod bool; pub mod dice; +pub mod integer; #[cfg(feature = "uuid_crate")] pub mod uuid; @@ -9,5 +10,6 @@ pub use command::Command as Random; pub use self::bool::SubCommand as RandomBool; pub use dice::SubCommand as RandomDice; +pub use integer::SubCommand as RandomInteger; #[cfg(feature = "uuid_crate")] pub use uuid::SubCommand as RandomUUID; diff --git a/crates/nu-cli/tests/commands/random/integer.rs b/crates/nu-cli/tests/commands/random/integer.rs new file mode 100644 index 0000000000..e25d6a1f52 --- /dev/null +++ b/crates/nu-cli/tests/commands/random/integer.rs @@ -0,0 +1,13 @@ +use nu_test_support::{nu, pipeline}; + +#[test] +fn generates_an_integer() { + let actual = nu!( + cwd: ".", pipeline( + r#" + random integer --min 42 --max 43 + "# + )); + + assert!(actual.out.contains("42") || actual.out.contains("43")); +} diff --git a/crates/nu-cli/tests/commands/random/mod.rs b/crates/nu-cli/tests/commands/random/mod.rs index 4d82049428..7b7b33064e 100644 --- a/crates/nu-cli/tests/commands/random/mod.rs +++ b/crates/nu-cli/tests/commands/random/mod.rs @@ -1,4 +1,5 @@ mod bool; mod dice; +mod integer; #[cfg(feature = "uuid_crate")] mod uuid; diff --git a/docs/commands/random.md b/docs/commands/random.md index d69345e8fb..143dde1423 100644 --- a/docs/commands/random.md +++ b/docs/commands/random.md @@ -88,3 +88,34 @@ true > random uuid 8af4de39-acbc-42f0-94d1-7cfad6c01f8b ``` + +## integer + +* `random integer`: Generate a random integer + +### integer Flags + +* `m`, `--min` \: The minimum value to generate +* `x`, `--max` \: The maximum value to generate + +### integer Examples + +```shell +> random integer +42 +``` + +```shell +> random integer --min 5000 +8700890823 +``` + +```shell +> random integer --max 100 +73 +``` + +```shell +> random integer --min 100000 --max 200000 +173400 +```