messagepack_cli/
conversion.rs1use std::{
4 fmt::Debug,
5 io::{Read, Write},
6};
7
8use error_stack::{report, Report, ResultExt};
9use rmp_serde::config::{DefaultConfig, StructMapConfig};
10use serde_json::ser::PrettyFormatter;
11
12use crate::Error;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum ConversionDirection {
17 Auto,
19 MsgPack2Json,
21 Json2MsgPack,
23}
24
25pub struct Converter<I, O> {
28 input: I,
30 output: O,
32 direction: ConversionDirection,
34}
35
36impl<I, O> Converter<I, O>
37where
38 I: Read,
39 O: Write,
40{
41 #[must_use]
44 pub fn new(input: I, output: O, direction: ConversionDirection) -> Self {
45 Self { input, output, direction }
46 }
47
48 pub fn execute(mut self) -> Result<(), Report<Error>> {
50 match self.direction {
51 ConversionDirection::Auto => self.automatic_conversion()?,
52 ConversionDirection::MsgPack2Json => {
53 let mut deserializer = msgpack_deserializer(self.input);
54 let mut serializer = json_serializer(&mut self.output);
55 serde_transcode::transcode(&mut deserializer, &mut serializer)
56 .change_context(Error::Transcoding)?;
57 }
58 ConversionDirection::Json2MsgPack => {
59 let mut deserializer = json_deserializer(self.input);
60 let mut serializer = msgpack_serializer(&mut self.output);
61 serde_transcode::transcode(&mut deserializer, &mut serializer)
62 .change_context(Error::Transcoding)?;
63 }
64 }
65 self.output.write(&[b'\n']).change_context(Error::FileWrite)?;
66 Ok(())
67 }
68
69 fn automatic_conversion(&mut self) -> Result<(), Report<Error>> {
73 let mut data = Vec::new();
74 self.input.read_to_end(&mut data).change_context(Error::FileRead)?;
75 let mut error = report!(Error::AutomaticDetection);
76
77 let mut output = Vec::new();
79 let mut deserializer = json_deserializer(data.as_slice());
80 let mut serializer = msgpack_serializer(&mut output);
81 let res = serde_transcode::transcode(&mut deserializer, &mut serializer)
82 .change_context(Error::Transcoding);
83 match res {
84 Ok(_) => return self.output.write_all(&output).change_context(Error::FileWrite),
85 Err(err) => error.extend_one(err),
86 }
87 drop(output); let mut deserializer = msgpack_deserializer(data.as_slice());
91 let mut serializer = json_serializer(&mut self.output);
92 let res = serde_transcode::transcode(&mut deserializer, &mut serializer)
93 .change_context(Error::Transcoding);
94 match res {
95 Ok(_) => return Ok(()),
96 Err(err) => error.extend_one(err),
97 }
98
99 Err(error)
101 }
102}
103
104fn msgpack_deserializer<R: Read>(
106 reader: R,
107) -> rmp_serde::Deserializer<rmp_serde::decode::ReadReader<R>> {
108 rmp_serde::Deserializer::new(reader)
109}
110
111fn msgpack_serializer<W: Write>(
113 writer: W,
114) -> rmp_serde::Serializer<W, StructMapConfig<DefaultConfig>> {
115 rmp_serde::Serializer::new(writer).with_struct_map()
116}
117
118fn json_deserializer<R: Read>(reader: R) -> serde_json::Deserializer<serde_json::de::IoRead<R>> {
120 serde_json::Deserializer::from_reader(reader)
121}
122
123fn json_serializer<W: Write>(writer: W) -> serde_json::Serializer<W, PrettyFormatter<'static>> {
125 serde_json::Serializer::pretty(writer)
126}
127
128impl<I, O> Debug for Converter<I, O> {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 f.debug_struct("Converter")
131 .field("input", &"<redacted>")
132 .field("output", &"<redacted>")
133 .field("direction", &self.direction)
134 .finish()
135 }
136}