nu_cmd_lang/core_commands/
match_.rs

1use nu_engine::command_prelude::*;
2use nu_protocol::engine::CommandType;
3
4#[derive(Clone)]
5pub struct Match;
6
7impl Command for Match {
8    fn name(&self) -> &str {
9        "match"
10    }
11
12    fn description(&self) -> &str {
13        "Conditionally run a block on a matched value."
14    }
15
16    fn signature(&self) -> nu_protocol::Signature {
17        Signature::build("match")
18            .input_output_types(vec![(Type::Any, Type::Any)])
19            .required("value", SyntaxShape::Any, "Value to check.")
20            .required(
21                "match_block",
22                SyntaxShape::MatchBlock,
23                "Block to run if check succeeds.",
24            )
25            .category(Category::Core)
26    }
27
28    fn extra_description(&self) -> &str {
29        r#"This command is a parser keyword. For details, check:
30  https://www.nushell.sh/book/thinking_in_nu.html"#
31    }
32
33    fn command_type(&self) -> CommandType {
34        CommandType::Keyword
35    }
36
37    fn run(
38        &self,
39        _engine_state: &EngineState,
40        _stack: &mut Stack,
41        _call: &Call,
42        _input: PipelineData,
43    ) -> Result<PipelineData, ShellError> {
44        // This is compiled specially by the IR compiler. The code here is never used when
45        // running in IR mode.
46        eprintln!(
47            "Tried to execute 'run' for the 'match' command: this code path should never be reached in IR mode"
48        );
49        unreachable!()
50    }
51
52    fn examples(&self) -> Vec<Example<'_>> {
53        vec![
54            Example {
55                description: "Match on a value",
56                example: "match 3 { 1 => 'one', 2 => 'two', 3 => 'three' }",
57                result: Some(Value::test_string("three")),
58            },
59            Example {
60                description: "Match against alternative values",
61                example: "match 'three' { 1 | 'one' => '-', 2 | 'two' => '--', 3 | 'three' => '---' }",
62                result: Some(Value::test_string("---")),
63            },
64            Example {
65                description: "Match on a value in range",
66                example: "match 3 { 1..10 => 'yes!' }",
67                result: Some(Value::test_string("yes!")),
68            },
69            Example {
70                description: "Match on a field in a record",
71                example: "match {a: 100} { {a: $my_value} => { $my_value } }",
72                result: Some(Value::test_int(100)),
73            },
74            Example {
75                description: "Match with a catch-all",
76                example: "match 3 { 1 => { 'yes!' }, _ => { 'no!' } }",
77                result: Some(Value::test_string("no!")),
78            },
79            Example {
80                description: "Match against a list",
81                example: "match [1, 2, 3] { [$a, $b, $c] => { $a + $b + $c }, _ => 0 }",
82                result: Some(Value::test_int(6)),
83            },
84            Example {
85                description: "Match against pipeline input",
86                example: "{a: {b: 3}} | match $in {{a: { $b }} => ($b + 10) }",
87                result: Some(Value::test_int(13)),
88            },
89            Example {
90                description: "Match with a guard",
91                example: "match [1 2 3] {
92        [$x, ..$y] if $x == 1 => { 'good list' },
93        _ => { 'not a very good list' }
94    }
95    ",
96                result: Some(Value::test_string("good list")),
97            },
98        ]
99    }
100}
101
102#[cfg(test)]
103mod test {
104    use super::*;
105
106    #[test]
107    fn test_examples() {
108        use crate::test_examples;
109
110        test_examples(Match {})
111    }
112}