diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 704f520ca..073fbddf8 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -266,6 +266,7 @@ pub fn create_default_context(interactive: bool) -> Result>, +} + +const DEFAULT_CHARS_LENGTH: u32 = 25; + +#[async_trait] +impl WholeStreamCommand for SubCommand { + fn name(&self) -> &str { + "random chars" + } + + fn signature(&self) -> Signature { + Signature::build("random chars").named( + "length", + SyntaxShape::Int, + "Number of chars", + Some('l'), + ) + } + + fn usage(&self) -> &str { + "Generate random chars" + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + chars(args, registry).await + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Generate random chars", + example: "random chars", + result: None, + }, + Example { + description: "Generate random chars with specified length", + example: "random chars -l 20", + result: None, + }, + ] + } +} + +pub async fn chars( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let (CharsArgs { length }, _) = args.process(®istry).await?; + + let chars_length = length.map_or(DEFAULT_CHARS_LENGTH, |l| l.item); + + let random_string: String = thread_rng() + .sample_iter(&Alphanumeric) + .take(chars_length as usize) + .collect(); + + let result = UntaggedValue::string(random_string); + Ok(OutputStream::one(ReturnSuccess::value(result))) +} + +#[cfg(test)] +mod tests { + use super::ShellError; + use super::SubCommand; + + #[test] + fn examples_work_as_expected() -> Result<(), ShellError> { + use crate::examples::test as test_examples; + + Ok(test_examples(SubCommand {})?) + } +} diff --git a/crates/nu-cli/src/commands/random/mod.rs b/crates/nu-cli/src/commands/random/mod.rs index 330173b42..5decd9475 100644 --- a/crates/nu-cli/src/commands/random/mod.rs +++ b/crates/nu-cli/src/commands/random/mod.rs @@ -1,6 +1,7 @@ pub mod command; pub mod bool; +pub mod chars; pub mod decimal; pub mod dice; pub mod integer; @@ -10,6 +11,7 @@ pub mod uuid; pub use command::Command as Random; pub use self::bool::SubCommand as RandomBool; +pub use chars::SubCommand as RandomChars; pub use decimal::SubCommand as RandomDecimal; pub use dice::SubCommand as RandomDice; pub use integer::SubCommand as RandomInteger; diff --git a/crates/nu-cli/tests/commands/random/chars.rs b/crates/nu-cli/tests/commands/random/chars.rs new file mode 100644 index 000000000..c77f34736 --- /dev/null +++ b/crates/nu-cli/tests/commands/random/chars.rs @@ -0,0 +1,14 @@ +use nu_test_support::{nu, pipeline}; + +#[test] +fn generates_chars_of_specified_length() { + let actual = nu!( + cwd: ".", pipeline( + r#" + random chars -l 15 | size | get chars + "# + )); + + let result = actual.out; + assert_eq!(result, "15"); +} diff --git a/crates/nu-cli/tests/commands/random/mod.rs b/crates/nu-cli/tests/commands/random/mod.rs index f3e765602..9b3bf6eb8 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 chars; mod decimal; mod dice; mod integer; diff --git a/docs/commands/random.md b/docs/commands/random.md index d65c27faa..acd37b119 100644 --- a/docs/commands/random.md +++ b/docs/commands/random.md @@ -119,3 +119,10 @@ true > random integer 100000..200000 173400 ``` + +### chars Examples +Generate a random password of length 15 +```shell +> random chars -l 15 +fWBSbE7QtaoJGeo +``` \ No newline at end of file