nu_command/bytes/
length.rs

1use nu_cmd_base::input_handler::{CellPathOnlyArgs, operate};
2use nu_engine::command_prelude::*;
3
4#[derive(Clone)]
5pub struct BytesLen;
6
7impl Command for BytesLen {
8    fn name(&self) -> &str {
9        "bytes length"
10    }
11
12    fn signature(&self) -> Signature {
13        Signature::build("bytes length")
14            .input_output_types(vec![
15                (Type::Binary, Type::Int),
16                (
17                    Type::List(Box::new(Type::Binary)),
18                    Type::List(Box::new(Type::Int)),
19                ),
20                (Type::table(), Type::table()),
21                (Type::record(), Type::record()),
22            ])
23            .allow_variants_without_examples(true)
24            .rest(
25                "rest",
26                SyntaxShape::CellPath,
27                "For a data structure input, find the length of data at the given cell paths.",
28            )
29            .category(Category::Bytes)
30    }
31
32    fn description(&self) -> &str {
33        "Output the length of any bytes in the pipeline."
34    }
35
36    fn search_terms(&self) -> Vec<&str> {
37        vec!["size", "count"]
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        let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 1)?;
48        let arg = CellPathOnlyArgs::from(cell_paths);
49        operate(length, arg, input, call.head, engine_state.signals())
50    }
51
52    fn examples(&self) -> Vec<Example<'_>> {
53        vec![
54            Example {
55                description: "Return the length of a binary",
56                example: "0x[1F FF AA AB] | bytes length",
57                result: Some(Value::test_int(4)),
58            },
59            Example {
60                description: "Return the lengths of multiple binaries",
61                example: "[0x[1F FF AA AB] 0x[1F]] | bytes length",
62                result: Some(Value::list(
63                    vec![Value::test_int(4), Value::test_int(1)],
64                    Span::test_data(),
65                )),
66            },
67        ]
68    }
69}
70
71fn length(val: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value {
72    let val_span = val.span();
73    match val {
74        Value::Binary { val, .. } => Value::int(val.len() as i64, val_span),
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 test {
91    use super::*;
92
93    #[test]
94    fn test_examples() {
95        use crate::test_examples;
96
97        test_examples(BytesLen {})
98    }
99}