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