From d53b0a99d0d870506a81a89794348a27d501540a Mon Sep 17 00:00:00 2001 From: Stefan Holderbach Date: Tue, 12 Sep 2023 13:03:05 +0200 Subject: [PATCH] Rename `random decimal` to `random float` (#10320) # Description Similar to #9979 # User-Facing Changes `random decimal` will now raise a warning and can be removed in an upcoming release. New command is named `random float` # Tests + Formatting Tests updated and improved. --- crates/nu-command/src/default_context.rs | 1 + crates/nu-command/src/random/decimal.rs | 24 +++- crates/nu-command/src/random/float.rs | 122 ++++++++++++++++++ crates/nu-command/src/random/mod.rs | 2 + .../tests/commands/random/decimal.rs | 22 ---- .../nu-command/tests/commands/random/float.rs | 26 ++++ .../nu-command/tests/commands/random/mod.rs | 2 +- 7 files changed, 171 insertions(+), 28 deletions(-) create mode 100644 crates/nu-command/src/random/float.rs delete mode 100644 crates/nu-command/tests/commands/random/decimal.rs create mode 100644 crates/nu-command/tests/commands/random/float.rs diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index bd73636d11..b1a64f39f8 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -368,6 +368,7 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState { RandomChars, RandomDecimal, RandomDice, + RandomFloat, RandomInteger, RandomUuid, }; diff --git a/crates/nu-command/src/random/decimal.rs b/crates/nu-command/src/random/decimal.rs index fd11f8c703..c71dfe57f3 100644 --- a/crates/nu-command/src/random/decimal.rs +++ b/crates/nu-command/src/random/decimal.rs @@ -24,7 +24,11 @@ impl Command for SubCommand { } fn usage(&self) -> &str { - "Generate a random decimal within a range [min..max]." + "deprecated: Generate a random float within a range [min..max]." + } + + fn extra_usage(&self) -> &str { + "Use `random float` instead" } fn search_terms(&self) -> Vec<&str> { @@ -38,28 +42,38 @@ impl Command for SubCommand { call: &Call, _input: PipelineData, ) -> Result { + nu_protocol::report_error_new( + engine_state, + &ShellError::GenericError( + "Deprecated command".into(), + "`random decimal` is deprecated and will be removed in 0.86.".into(), + Some(call.head), + Some("Use `random float instead".into()), + vec![], + ), + ); decimal(engine_state, stack, call) } fn examples(&self) -> Vec { vec![ Example { - description: "Generate a default decimal value between 0 and 1", + description: "Generate a default float value between 0 and 1", example: "random decimal", result: None, }, Example { - description: "Generate a random decimal less than or equal to 500", + description: "Generate a random float less than or equal to 500", example: "random decimal ..500", result: None, }, Example { - description: "Generate a random decimal greater than or equal to 100000", + description: "Generate a random float greater than or equal to 100000", example: "random decimal 100000..", result: None, }, Example { - description: "Generate a random decimal between 1.0 and 1.1", + description: "Generate a random float between 1.0 and 1.1", example: "random decimal 1.0..1.1", result: None, }, diff --git a/crates/nu-command/src/random/float.rs b/crates/nu-command/src/random/float.rs new file mode 100644 index 0000000000..7aeb694a61 --- /dev/null +++ b/crates/nu-command/src/random/float.rs @@ -0,0 +1,122 @@ +use nu_engine::CallExt; +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{ + Category, Example, PipelineData, Range, ShellError, Signature, Span, SyntaxShape, Type, Value, +}; +use rand::prelude::{thread_rng, Rng}; +use std::cmp::Ordering; + +#[derive(Clone)] +pub struct SubCommand; + +impl Command for SubCommand { + fn name(&self) -> &str { + "random float" + } + + fn signature(&self) -> Signature { + Signature::build("random float") + .input_output_types(vec![(Type::Nothing, Type::Float)]) + .allow_variants_without_examples(true) + .optional("range", SyntaxShape::Range, "Range of values") + .category(Category::Random) + } + + fn usage(&self) -> &str { + "Generate a random float within a range [min..max]." + } + + fn search_terms(&self) -> Vec<&str> { + vec!["generate"] + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + _input: PipelineData, + ) -> Result { + float(engine_state, stack, call) + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Generate a default float value between 0 and 1", + example: "random float", + result: None, + }, + Example { + description: "Generate a random float less than or equal to 500", + example: "random float ..500", + result: None, + }, + Example { + description: "Generate a random float greater than or equal to 100000", + example: "random float 100000..", + result: None, + }, + Example { + description: "Generate a random float between 1.0 and 1.1", + example: "random float 1.0..1.1", + result: None, + }, + ] + } +} + +fn float( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { + let span = call.head; + let range: Option = call.opt(engine_state, stack, 0)?; + + let (min, max) = if let Some(r) = range { + if r.is_end_inclusive() { + (r.from.as_float()?, r.to.as_float()?) + } else if r.to.as_float()? >= 1.0 { + (r.from.as_float()?, r.to.as_float()? - 1.0) + } else { + (0.0, 0.0) + } + } else { + (0.0, 1.0) + }; + + match min.partial_cmp(&max) { + Some(Ordering::Greater) => Err(ShellError::InvalidRange { + left_flank: min.to_string(), + right_flank: max.to_string(), + span, + }), + Some(Ordering::Equal) => Ok(PipelineData::Value( + Value::float(min, Span::new(64, 64)), + None, + )), + _ => { + let mut thread_rng = thread_rng(); + let result: f64 = thread_rng.gen_range(min..max); + + Ok(PipelineData::Value( + Value::float(result, Span::new(64, 64)), + None, + )) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_examples() { + use crate::test_examples; + + test_examples(SubCommand {}) + } +} diff --git a/crates/nu-command/src/random/mod.rs b/crates/nu-command/src/random/mod.rs index 19e2f36103..898aaa3fc9 100644 --- a/crates/nu-command/src/random/mod.rs +++ b/crates/nu-command/src/random/mod.rs @@ -2,6 +2,7 @@ mod bool; mod chars; mod decimal; mod dice; +mod float; mod integer; mod random_; mod uuid; @@ -10,6 +11,7 @@ pub use self::bool::SubCommand as RandomBool; pub use self::chars::SubCommand as RandomChars; pub use self::decimal::SubCommand as RandomDecimal; pub use self::dice::SubCommand as RandomDice; +pub use self::float::SubCommand as RandomFloat; pub use self::integer::SubCommand as RandomInteger; pub use self::uuid::SubCommand as RandomUuid; pub use random_::RandomCommand as Random; diff --git a/crates/nu-command/tests/commands/random/decimal.rs b/crates/nu-command/tests/commands/random/decimal.rs deleted file mode 100644 index 8682f236ff..0000000000 --- a/crates/nu-command/tests/commands/random/decimal.rs +++ /dev/null @@ -1,22 +0,0 @@ -use nu_test_support::nu; - -#[test] -fn generates_a_decimal() { - let actual = nu!("random decimal 42..43"); - - assert!(actual.out.contains("42") || actual.out.contains("43")); -} - -#[test] -fn generates_55() { - let actual = nu!("random decimal 55..55"); - - assert!(actual.out.contains("55")); -} - -#[test] -fn generates_0() { - let actual = nu!(" random decimal ..<1 "); - - assert!(actual.out.contains('0')); -} diff --git a/crates/nu-command/tests/commands/random/float.rs b/crates/nu-command/tests/commands/random/float.rs new file mode 100644 index 0000000000..1fb7a2f6fc --- /dev/null +++ b/crates/nu-command/tests/commands/random/float.rs @@ -0,0 +1,26 @@ +use nu_test_support::nu; + +#[test] +fn generates_a_float() { + let actual = nu!("random float 42..43"); + + // Attention: this relies on the string output + assert!(actual.out.starts_with("42") || actual.out.starts_with("43")); + let actual = nu!("random float 42..43 | describe"); + + assert_eq!(actual.out, "float") +} + +#[test] +fn generates_55() { + let actual = nu!("random float 55..55"); + + assert!(actual.out.contains("55")); +} + +#[test] +fn generates_0() { + let actual = nu!("random float ..<1"); + + assert!(actual.out.contains('0')); +} diff --git a/crates/nu-command/tests/commands/random/mod.rs b/crates/nu-command/tests/commands/random/mod.rs index 9b3bf6eb88..c0dc226498 100644 --- a/crates/nu-command/tests/commands/random/mod.rs +++ b/crates/nu-command/tests/commands/random/mod.rs @@ -1,7 +1,7 @@ mod bool; mod chars; -mod decimal; mod dice; +mod float; mod integer; #[cfg(feature = "uuid_crate")] mod uuid;