nu_plugin_core/serializers/
msgpack.rs1use std::io::ErrorKind;
2
3use nu_plugin_protocol::{PluginInput, PluginOutput};
4use nu_protocol::{
5 ShellError,
6 shell_error::{self, io::IoError},
7};
8use serde::Deserialize;
9
10use crate::{Encoder, PluginEncoder};
11
12#[derive(Clone, Copy, Debug)]
17pub struct MsgPackSerializer;
18
19impl PluginEncoder for MsgPackSerializer {
20 fn name(&self) -> &str {
21 "msgpack"
22 }
23}
24
25impl Encoder<PluginInput> for MsgPackSerializer {
26 fn encode(
27 &self,
28 plugin_input: &PluginInput,
29 writer: &mut impl std::io::Write,
30 ) -> Result<(), nu_protocol::ShellError> {
31 rmp_serde::encode::write_named(writer, plugin_input).map_err(rmp_encode_err)
32 }
33
34 fn decode(
35 &self,
36 reader: &mut impl std::io::BufRead,
37 ) -> Result<Option<PluginInput>, ShellError> {
38 let mut de = rmp_serde::Deserializer::new(reader);
39 PluginInput::deserialize(&mut de)
40 .map(Some)
41 .or_else(rmp_decode_err)
42 }
43}
44
45impl Encoder<PluginOutput> for MsgPackSerializer {
46 fn encode(
47 &self,
48 plugin_output: &PluginOutput,
49 writer: &mut impl std::io::Write,
50 ) -> Result<(), ShellError> {
51 rmp_serde::encode::write_named(writer, plugin_output).map_err(rmp_encode_err)
52 }
53
54 fn decode(
55 &self,
56 reader: &mut impl std::io::BufRead,
57 ) -> Result<Option<PluginOutput>, ShellError> {
58 let mut de = rmp_serde::Deserializer::new(reader);
59 PluginOutput::deserialize(&mut de)
60 .map(Some)
61 .or_else(rmp_decode_err)
62 }
63}
64
65fn rmp_encode_err(err: rmp_serde::encode::Error) -> ShellError {
67 match err {
68 rmp_serde::encode::Error::InvalidValueWrite(_) => {
69 ShellError::Io(IoError::new_internal(
71 shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
73 "Could not encode with rmp",
74 nu_protocol::location!(),
75 ))
76 }
77 _ => {
78 ShellError::PluginFailedToEncode {
80 msg: err.to_string(),
81 }
82 }
83 }
84}
85
86fn rmp_decode_err<T>(err: rmp_serde::decode::Error) -> Result<Option<T>, ShellError> {
88 match err {
89 rmp_serde::decode::Error::InvalidMarkerRead(err)
90 | rmp_serde::decode::Error::InvalidDataRead(err) => {
91 if matches!(err.kind(), ErrorKind::UnexpectedEof) {
92 Ok(None)
94 } else {
95 Err(ShellError::Io(IoError::new_internal(
97 shell_error::io::ErrorKind::from_std(std::io::ErrorKind::Other),
99 "Could not decode with rmp",
100 nu_protocol::location!(),
101 )))
102 }
103 }
104 _ => {
105 Err(ShellError::PluginFailedToDecode {
107 msg: err.to_string(),
108 })
109 }
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 crate::serializers::tests::generate_tests!(MsgPackSerializer {});
117}