nu_command/random/
bool.rs

1use nu_engine::command_prelude::*;
2use rand::random_bool;
3
4#[derive(Clone)]
5pub struct RandomBool;
6
7impl Command for RandomBool {
8    fn name(&self) -> &str {
9        "random bool"
10    }
11
12    fn signature(&self) -> Signature {
13        Signature::build("random bool")
14            .input_output_types(vec![(Type::Nothing, Type::Bool)])
15            .allow_variants_without_examples(true)
16            .named(
17                "bias",
18                SyntaxShape::Number,
19                "Adjusts the probability of a \"true\" outcome",
20                Some('b'),
21            )
22            .category(Category::Random)
23    }
24
25    fn description(&self) -> &str {
26        "Generate a random boolean value."
27    }
28
29    fn search_terms(&self) -> Vec<&str> {
30        vec!["generate", "boolean", "true", "false", "1", "0"]
31    }
32
33    fn run(
34        &self,
35        engine_state: &EngineState,
36        stack: &mut Stack,
37        call: &Call,
38        _input: PipelineData,
39    ) -> Result<PipelineData, ShellError> {
40        bool(engine_state, stack, call)
41    }
42
43    fn examples(&self) -> Vec<Example> {
44        vec![
45            Example {
46                description: "Generate a random boolean value",
47                example: "random bool",
48                result: None,
49            },
50            Example {
51                description: "Generate a random boolean value with a 75% chance of \"true\"",
52                example: "random bool --bias 0.75",
53                result: None,
54            },
55        ]
56    }
57}
58
59fn bool(
60    engine_state: &EngineState,
61    stack: &mut Stack,
62    call: &Call,
63) -> Result<PipelineData, ShellError> {
64    let span = call.head;
65    let bias: Option<Spanned<f64>> = call.get_flag(engine_state, stack, "bias")?;
66
67    let mut probability = 0.5;
68
69    if let Some(prob) = bias {
70        probability = prob.item;
71
72        let probability_is_valid = (0.0..=1.0).contains(&probability);
73
74        if !probability_is_valid {
75            return Err(ShellError::InvalidProbability { span: prob.span });
76        }
77    }
78
79    let bool_result: bool = random_bool(probability);
80
81    Ok(PipelineData::value(Value::bool(bool_result, span), None))
82}
83
84#[cfg(test)]
85mod test {
86    use super::*;
87
88    #[test]
89    fn test_examples() {
90        use crate::test_examples;
91
92        test_examples(RandomBool {})
93    }
94}