nu_command/bytes/
reverse.rs

1use nu_cmd_base::input_handler::{CellPathOnlyArgs, operate};
2use nu_engine::command_prelude::*;
3
4#[derive(Clone)]
5pub struct BytesReverse;
6
7impl Command for BytesReverse {
8    fn name(&self) -> &str {
9        "bytes reverse"
10    }
11
12    fn signature(&self) -> Signature {
13        Signature::build("bytes reverse")
14            .input_output_types(vec![
15                (Type::Binary, Type::Binary),
16                (Type::table(), Type::table()),
17                (Type::record(), Type::record()),
18            ])
19            .allow_variants_without_examples(true)
20            .rest(
21                "rest",
22                SyntaxShape::CellPath,
23                "For a data structure input, reverse data at the given cell paths.",
24            )
25            .category(Category::Bytes)
26    }
27
28    fn description(&self) -> &str {
29        "Reverse the bytes in the pipeline."
30    }
31
32    fn search_terms(&self) -> Vec<&str> {
33        vec!["convert", "inverse", "flip"]
34    }
35
36    fn run(
37        &self,
38        engine_state: &EngineState,
39        stack: &mut Stack,
40        call: &Call,
41        input: PipelineData,
42    ) -> Result<PipelineData, ShellError> {
43        let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
44        let arg = CellPathOnlyArgs::from(cell_paths);
45        operate(reverse, arg, input, call.head, engine_state.signals())
46    }
47
48    fn examples(&self) -> Vec<Example> {
49        vec![
50            Example {
51                description: "Reverse bytes `0x[1F FF AA AA]`",
52                example: "0x[1F FF AA AA] | bytes reverse",
53                result: Some(Value::binary(
54                    vec![0xAA, 0xAA, 0xFF, 0x1F],
55                    Span::test_data(),
56                )),
57            },
58            Example {
59                description: "Reverse bytes `0x[FF AA AA]`",
60                example: "0x[FF AA AA] | bytes reverse",
61                result: Some(Value::binary(vec![0xAA, 0xAA, 0xFF], Span::test_data())),
62            },
63        ]
64    }
65}
66
67fn reverse(val: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
68    let val_span = val.span();
69    match val {
70        Value::Binary { val, .. } => {
71            let mut reversed_input = val.to_vec();
72            reversed_input.reverse();
73            Value::binary(reversed_input, val_span)
74        }
75        // Propagate errors by explicitly matching them before the final case.
76        Value::Error { .. } => val.clone(),
77        other => Value::error(
78            ShellError::OnlySupportsThisInputType {
79                exp_input_type: "binary".into(),
80                wrong_type: other.get_type().to_string(),
81                dst_span: span,
82                src_span: other.span(),
83            },
84            span,
85        ),
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn test_examples() {
95        use crate::test_examples;
96
97        test_examples(BytesReverse {})
98    }
99}