nu_command/bytes/
collect.rs1use itertools::Itertools;
2use nu_engine::command_prelude::*;
3
4#[derive(Clone, Copy)]
5pub struct BytesCollect;
6
7impl Command for BytesCollect {
8 fn name(&self) -> &str {
9 "bytes collect"
10 }
11
12 fn signature(&self) -> Signature {
13 Signature::build("bytes collect")
14 .input_output_types(vec![(Type::List(Box::new(Type::Binary)), Type::Binary)])
15 .optional(
16 "separator",
17 SyntaxShape::Binary,
18 "Optional separator to use when creating binary.",
19 )
20 .category(Category::Bytes)
21 }
22
23 fn description(&self) -> &str {
24 "Concatenate multiple binary into a single binary, with an optional separator between each."
25 }
26
27 fn search_terms(&self) -> Vec<&str> {
28 vec!["join", "concatenate"]
29 }
30
31 fn run(
32 &self,
33 engine_state: &EngineState,
34 stack: &mut Stack,
35 call: &Call,
36 input: PipelineData,
37 ) -> Result<PipelineData, ShellError> {
38 let separator: Option<Vec<u8>> = call.opt(engine_state, stack, 0)?;
39
40 let span = call.head;
41
42 let metadata = input.metadata();
44 let iter = Itertools::intersperse(
45 input.into_iter_strict(span)?.map(move |value| {
46 Some(match value {
48 Value::Error { error, .. } => Err(*error),
50 Value::Binary { val, .. } => Ok(val),
51 other => Err(ShellError::OnlySupportsThisInputType {
52 exp_input_type: "binary".into(),
53 wrong_type: other.get_type().to_string(),
54 dst_span: span,
55 src_span: other.span(),
56 }),
57 })
58 }),
59 Ok(separator).transpose(),
60 )
61 .flatten();
62
63 let output = ByteStream::from_result_iter(
64 iter,
65 span,
66 engine_state.signals().clone(),
67 ByteStreamType::Binary,
68 );
69
70 Ok(PipelineData::byte_stream(output, metadata))
71 }
72
73 fn examples(&self) -> Vec<Example> {
74 vec![
75 Example {
76 description: "Create a byte array from input",
77 example: "[0x[11] 0x[13 15]] | bytes collect",
78 result: Some(Value::binary(vec![0x11, 0x13, 0x15], Span::test_data())),
79 },
80 Example {
81 description: "Create a byte array from input with a separator",
82 example: "[0x[11] 0x[33] 0x[44]] | bytes collect 0x[01]",
83 result: Some(Value::binary(
84 vec![0x11, 0x01, 0x33, 0x01, 0x44],
85 Span::test_data(),
86 )),
87 },
88 ]
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 #[test]
96 fn test_examples() {
97 use crate::test_examples;
98
99 test_examples(BytesCollect {})
100 }
101}