diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index f20f774452..9ad236173b 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -394,6 +394,7 @@ pub fn create_default_context( // Random value generation whole_stream_command(Random), whole_stream_command(RandomBool), + whole_stream_command(RandomDice), whole_stream_command(RandomUUID), ]); diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index d35f6ee15b..d0b7b09528 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -219,7 +219,7 @@ pub(crate) use pivot::Pivot; pub(crate) use prepend::Prepend; pub(crate) use prev::Previous; pub(crate) use pwd::Pwd; -pub(crate) use random::{Random, RandomBool, RandomUUID}; +pub(crate) use random::{Random, RandomBool, RandomDice, RandomUUID}; pub(crate) use range::Range; #[allow(unused_imports)] pub(crate) use reduce_by::ReduceBy; diff --git a/crates/nu-cli/src/commands/random/dice.rs b/crates/nu-cli/src/commands/random/dice.rs new file mode 100644 index 0000000000..d43414cf9b --- /dev/null +++ b/crates/nu-cli/src/commands/random/dice.rs @@ -0,0 +1,103 @@ +use crate::commands::WholeStreamCommand; +use crate::prelude::*; +use nu_errors::ShellError; +use nu_protocol::{Signature, SyntaxShape, UntaggedValue}; +use nu_source::Tagged; +use rand::prelude::{thread_rng, Rng}; + +pub struct SubCommand; + +#[derive(Deserialize)] +pub struct DiceArgs { + dice: Option>, + sides: Option>, +} + +#[async_trait] +impl WholeStreamCommand for SubCommand { + fn name(&self) -> &str { + "random dice" + } + + fn signature(&self) -> Signature { + Signature::build("random dice") + .named( + "dice", + SyntaxShape::Int, + "The amount of dice being rolled", + Some('d'), + ) + .named( + "sides", + SyntaxShape::Int, + "The amount of sides a die has", + Some('s'), + ) + } + + fn usage(&self) -> &str { + "Generate a random dice roll" + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + dice(args, registry).await + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Roll 1 dice with 6 sides each", + example: "random dice", + result: None, + }, + Example { + description: "Roll 10 dice with 12 sides each", + example: "random dice -d 10 -s 12", + result: None, + }, + ] + } +} + +pub async fn dice( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let tag = args.call_info.name_tag.clone(); + let (DiceArgs { dice, sides }, _) = args.process(®istry).await?; + + let dice = if let Some(dice_tagged) = dice { + *dice_tagged + } else { + 1 + }; + + let sides = if let Some(sides_tagged) = sides { + *sides_tagged + } else { + 6 + }; + + let iter = (0..dice).map(move |_| { + let mut thread_rng = thread_rng(); + UntaggedValue::int(thread_rng.gen_range(1, sides + 1)).into_value(tag.clone()) + }); + + Ok(futures::stream::iter(iter).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/random/mod.rs b/crates/nu-cli/src/commands/random/mod.rs index 80a0b32cb6..3f1b9e8974 100644 --- a/crates/nu-cli/src/commands/random/mod.rs +++ b/crates/nu-cli/src/commands/random/mod.rs @@ -1,7 +1,11 @@ -pub mod bool; pub mod command; + +pub mod bool; +pub mod dice; pub mod uuid; -pub use self::bool::SubCommand as RandomBool; pub use command::Command as Random; + +pub use self::bool::SubCommand as RandomBool; +pub use dice::SubCommand as RandomDice; pub use uuid::SubCommand as RandomUUID; diff --git a/crates/nu-cli/tests/commands/random/dice.rs b/crates/nu-cli/tests/commands/random/dice.rs new file mode 100644 index 0000000000..c302fc1c11 --- /dev/null +++ b/crates/nu-cli/tests/commands/random/dice.rs @@ -0,0 +1,13 @@ +use nu_test_support::{nu, pipeline}; + +#[test] +fn rolls_4_roll() { + let actual = nu!( + cwd: ".", pipeline( + r#" + random dice -d 4 -s 10 | count + "# + )); + + assert_eq!(actual.out, "4"); +} diff --git a/crates/nu-cli/tests/commands/random/mod.rs b/crates/nu-cli/tests/commands/random/mod.rs index 4cf161e026..52dbdc2f8f 100644 --- a/crates/nu-cli/tests/commands/random/mod.rs +++ b/crates/nu-cli/tests/commands/random/mod.rs @@ -1,2 +1,3 @@ mod bool; +mod dice; mod uuid; diff --git a/docs/commands/random.md b/docs/commands/random.md index 44df1b0bd5..39bbf83b52 100644 --- a/docs/commands/random.md +++ b/docs/commands/random.md @@ -2,17 +2,6 @@ Use `random` to generate random values -## uuid - -* `random uuid`: Generate a random uuid4 string - -### uuid Examples - -```shell -> random uuid -8af4de39-acbc-42f0-94d1-7cfad6c01f8b -``` - ## bool * `random bool`: Generate a random boolean value @@ -32,3 +21,46 @@ false > random bool --bias 0.75 true ``` + +## dice + +* `random dice`: Generate a random dice roll + +### dice Flags + +* `d`, `--dice` \: The amount of dice being rolled +* `s`, `--sides` \: The amount of sides a die has + +### dice Examples + +```shell +> random dice +4 +``` + +```shell +> random dice -d 10 -s 12 +───┬──── + 0 │ 11 + 1 │ 11 + 2 │ 11 + 3 │ 11 + 4 │ 5 + 5 │ 3 + 6 │ 10 + 7 │ 7 + 8 │ 3 + 9 │ 1 +───┴──── +``` + +## uuid + +* `random uuid`: Generate a random uuid4 string + +### uuid Examples + +```shell +> random uuid +8af4de39-acbc-42f0-94d1-7cfad6c01f8b +```