nu_command/formats/from/
msgpackz.rs1use std::io::Cursor;
2
3use nu_engine::command_prelude::*;
4
5use super::msgpack::{Opts, read_msgpack};
6
7const BUFFER_SIZE: usize = 65536;
8
9#[derive(Clone)]
10pub struct FromMsgpackz;
11
12impl Command for FromMsgpackz {
13 fn name(&self) -> &str {
14 "from msgpackz"
15 }
16
17 fn signature(&self) -> Signature {
18 Signature::build(self.name())
19 .input_output_type(Type::Binary, Type::Any)
20 .switch("objects", "Read multiple objects from input", None)
21 .category(Category::Formats)
22 }
23
24 fn description(&self) -> &str {
25 "Convert brotli-compressed MessagePack data into Nu values."
26 }
27
28 fn extra_description(&self) -> &str {
29 "This is the format used by the plugin registry file ($nu.plugin-path)."
30 }
31
32 fn run(
33 &self,
34 engine_state: &EngineState,
35 stack: &mut Stack,
36 call: &Call,
37 input: PipelineData,
38 ) -> Result<PipelineData, ShellError> {
39 let span = input.span().unwrap_or(call.head);
40 let objects = call.has_flag(engine_state, stack, "objects")?;
41 let opts = Opts {
42 span,
43 objects,
44 signals: engine_state.signals().clone(),
45 };
46 let metadata = input.metadata().map(|md| md.with_content_type(None));
47 let out = match input {
48 PipelineData::Value(Value::Binary { val: bytes, .. }, _) => {
50 let reader = brotli::Decompressor::new(Cursor::new(bytes), BUFFER_SIZE);
51 read_msgpack(reader, opts)
52 }
53 PipelineData::ByteStream(stream, ..) => {
55 let span = stream.span();
56 if let Some(reader) = stream.reader() {
57 let reader = brotli::Decompressor::new(reader, BUFFER_SIZE);
58 read_msgpack(reader, opts)
59 } else {
60 Err(ShellError::PipelineMismatch {
61 exp_input_type: "binary or byte stream".into(),
62 dst_span: call.head,
63 src_span: span,
64 })
65 }
66 }
67 _ => Err(ShellError::PipelineMismatch {
68 exp_input_type: "binary or byte stream".into(),
69 dst_span: call.head,
70 src_span: span,
71 }),
72 };
73 out.map(|pd| pd.set_metadata(metadata))
74 }
75}