nu_command/random/
dice.rs1use nu_engine::command_prelude::*;
2use nu_protocol::ListStream;
3use rand::random_range;
4
5#[derive(Clone)]
6pub struct RandomDice;
7
8impl Command for RandomDice {
9 fn name(&self) -> &str {
10 "random dice"
11 }
12
13 fn signature(&self) -> Signature {
14 Signature::build("random dice")
15 .input_output_types(vec![(Type::Nothing, Type::list(Type::Int))])
16 .allow_variants_without_examples(true)
17 .named(
18 "dice",
19 SyntaxShape::Int,
20 "The amount of dice being rolled",
21 Some('d'),
22 )
23 .named(
24 "sides",
25 SyntaxShape::Int,
26 "The amount of sides a die has",
27 Some('s'),
28 )
29 .category(Category::Random)
30 }
31
32 fn description(&self) -> &str {
33 "Generate a random dice roll."
34 }
35
36 fn search_terms(&self) -> Vec<&str> {
37 vec!["generate", "die", "1-6"]
38 }
39
40 fn run(
41 &self,
42 engine_state: &EngineState,
43 stack: &mut Stack,
44 call: &Call,
45 _input: PipelineData,
46 ) -> Result<PipelineData, ShellError> {
47 dice(engine_state, stack, call)
48 }
49
50 fn examples(&self) -> Vec<Example> {
51 vec![
52 Example {
53 description: "Roll 1 dice with 6 sides each",
54 example: "random dice",
55 result: None,
56 },
57 Example {
58 description: "Roll 10 dice with 12 sides each",
59 example: "random dice --dice 10 --sides 12",
60 result: None,
61 },
62 ]
63 }
64}
65
66fn dice(
67 engine_state: &EngineState,
68 stack: &mut Stack,
69 call: &Call,
70) -> Result<PipelineData, ShellError> {
71 let span = call.head;
72
73 let dice: usize = call.get_flag(engine_state, stack, "dice")?.unwrap_or(1);
74 let sides: usize = call.get_flag(engine_state, stack, "sides")?.unwrap_or(6);
75
76 let iter = (0..dice).map(move |_| Value::int(random_range(1..sides + 1) as i64, span));
77
78 Ok(ListStream::new(iter, span, engine_state.signals().clone()).into())
79}
80
81#[cfg(test)]
82mod test {
83 use super::*;
84
85 #[test]
86 fn test_examples() {
87 use crate::test_examples;
88
89 test_examples(RandomDice {})
90 }
91}