facet_msgpack/
to_msgpack.rs1use facet_core::Facet;
2
3use facet_peek::Peek;
4use log::trace;
5use std::io::{self, Write};
6
7pub fn to_vec<T: Facet>(value: &T) -> Vec<u8> {
9 let mut buffer = Vec::new();
10 let peek = Peek::new(value);
11 serialize(peek, &mut buffer).unwrap();
12 buffer
13}
14
15fn serialize<W: Write>(peek: Peek<'_>, writer: &mut W) -> io::Result<()> {
17 match peek {
18 Peek::Value(pv) => {
19 trace!("Serializing scalar");
20 if pv.shape().is_type::<String>() {
21 let value = unsafe { pv.data().as_ref::<String>() };
22 write_str(writer, value)
23 } else if pv.shape().is_type::<u64>() {
24 let value = unsafe { pv.data().as_ref::<u64>() };
25 write_u64(writer, *value)
26 } else if pv.shape().is_type::<u32>() {
27 let value = unsafe { pv.data().as_ref::<u32>() };
28 write_u32(writer, *value)
29 } else if pv.shape().is_type::<u16>() {
30 let value = unsafe { pv.data().as_ref::<u16>() };
31 write_u16(writer, *value)
32 } else if pv.shape().is_type::<u8>() {
33 let value = unsafe { pv.data().as_ref::<u8>() };
34 write_u8(writer, *value)
35 } else if pv.shape().is_type::<i64>() {
36 let value = unsafe { pv.data().as_ref::<i64>() };
37 write_i64(writer, *value)
38 } else if pv.shape().is_type::<i32>() {
39 let value = unsafe { pv.data().as_ref::<i32>() };
40 write_i32(writer, *value)
41 } else if pv.shape().is_type::<i16>() {
42 let value = unsafe { pv.data().as_ref::<i16>() };
43 write_i16(writer, *value)
44 } else if pv.shape().is_type::<i8>() {
45 let value = unsafe { pv.data().as_ref::<i8>() };
46 write_i8(writer, *value)
47 } else {
48 todo!("Unsupported scalar type: {}", pv.shape())
49 }
50 }
51 Peek::Struct(ps) => {
52 trace!("Serializing struct");
53
54 let fields: Vec<_> = ps.fields().collect();
56 write_map_len(writer, fields.len())?;
57
58 for (name, field_peek) in fields {
60 write_str(writer, name)?;
61 serialize(field_peek, writer)?;
62 }
63 Ok(())
64 }
65 _ => {
66 todo!("Unsupported type: {:?}", peek)
67 }
68 }
69}
70
71fn write_str<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
72 let bytes = s.as_bytes();
73 let len = bytes.len();
74
75 match len {
76 0..=31 => {
77 writer.write_all(&[(0xa0 | len as u8)])?;
79 }
80 32..=255 => {
81 writer.write_all(&[0xd9, len as u8])?;
83 }
84 256..=65535 => {
85 writer.write_all(&[0xda])?;
87 writer.write_all(&(len as u16).to_be_bytes())?;
88 }
89 _ => {
90 writer.write_all(&[0xdb])?;
92 writer.write_all(&(len as u32).to_be_bytes())?;
93 }
94 }
95 writer.write_all(bytes)
96}
97
98fn write_u8<W: Write>(writer: &mut W, n: u8) -> io::Result<()> {
99 match n {
100 0..=127 => {
101 writer.write_all(&[n])
103 }
104 _ => {
105 writer.write_all(&[0xcc, n])
107 }
108 }
109}
110
111fn write_u16<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
112 match n {
113 0..=127 => {
114 writer.write_all(&[n as u8])
116 }
117 128..=255 => {
118 writer.write_all(&[0xcc, n as u8])
120 }
121 _ => {
122 writer.write_all(&[0xcd])?;
124 writer.write_all(&n.to_be_bytes())
125 }
126 }
127}
128
129fn write_u32<W: Write>(writer: &mut W, n: u32) -> io::Result<()> {
130 match n {
131 0..=127 => {
132 writer.write_all(&[n as u8])
134 }
135 128..=255 => {
136 writer.write_all(&[0xcc, n as u8])
138 }
139 256..=65535 => {
140 writer.write_all(&[0xcd])?;
142 writer.write_all(&(n as u16).to_be_bytes())
143 }
144 _ => {
145 writer.write_all(&[0xce])?;
147 writer.write_all(&n.to_be_bytes())
148 }
149 }
150}
151
152fn write_u64<W: Write>(writer: &mut W, n: u64) -> io::Result<()> {
153 match n {
154 0..=127 => {
155 writer.write_all(&[n as u8])
157 }
158 128..=255 => {
159 writer.write_all(&[0xcc, n as u8])
161 }
162 256..=65535 => {
163 writer.write_all(&[0xcd])?;
165 writer.write_all(&(n as u16).to_be_bytes())
166 }
167 65536..=4294967295 => {
168 writer.write_all(&[0xce])?;
170 writer.write_all(&(n as u32).to_be_bytes())
171 }
172 _ => {
173 writer.write_all(&[0xcf])?;
175 writer.write_all(&n.to_be_bytes())
176 }
177 }
178}
179
180fn write_i8<W: Write>(writer: &mut W, n: i8) -> io::Result<()> {
181 match n {
182 -32..=-1 => {
183 writer.write_all(&[n as u8])
185 }
186 -128..=-33 => {
187 writer.write_all(&[0xd0, n as u8])
189 }
190 0..=127 => {
191 writer.write_all(&[n as u8])
193 }
194 }
195}
196
197fn write_i16<W: Write>(writer: &mut W, n: i16) -> io::Result<()> {
198 match n {
199 -32..=-1 => {
200 writer.write_all(&[n as u8])
202 }
203 -128..=-33 => {
204 writer.write_all(&[0xd0, n as u8])
206 }
207 -32768..=-129 => {
208 writer.write_all(&[0xd1])?;
210 writer.write_all(&n.to_be_bytes())
211 }
212 0..=127 => {
213 writer.write_all(&[n as u8])
215 }
216 128..=255 => {
217 writer.write_all(&[0xcc, n as u8])
219 }
220 256..=32767 => {
221 writer.write_all(&[0xcd])?;
223 writer.write_all(&(n as u16).to_be_bytes())
224 }
225 }
226}
227
228fn write_i32<W: Write>(writer: &mut W, n: i32) -> io::Result<()> {
229 match n {
230 -32..=-1 => {
231 writer.write_all(&[n as u8])
233 }
234 -128..=-33 => {
235 writer.write_all(&[0xd0, n as u8])
237 }
238 -32768..=-129 => {
239 writer.write_all(&[0xd1])?;
241 writer.write_all(&(n as i16).to_be_bytes())
242 }
243 -2147483648..=-32769 => {
244 writer.write_all(&[0xd2])?;
246 writer.write_all(&n.to_be_bytes())
247 }
248 0..=127 => {
249 writer.write_all(&[n as u8])
251 }
252 128..=255 => {
253 writer.write_all(&[0xcc, n as u8])
255 }
256 256..=65535 => {
257 writer.write_all(&[0xcd])?;
259 writer.write_all(&(n as u16).to_be_bytes())
260 }
261 65536..=2147483647 => {
262 writer.write_all(&[0xce])?;
264 writer.write_all(&(n as u32).to_be_bytes())
265 }
266 }
267}
268
269fn write_i64<W: Write>(writer: &mut W, n: i64) -> io::Result<()> {
270 match n {
271 -32..=-1 => {
272 writer.write_all(&[n as u8])
274 }
275 -128..=-33 => {
276 writer.write_all(&[0xd0, n as u8])
278 }
279 -32768..=-129 => {
280 writer.write_all(&[0xd1])?;
282 writer.write_all(&(n as i16).to_be_bytes())
283 }
284 -2147483648..=-32769 => {
285 writer.write_all(&[0xd2])?;
287 writer.write_all(&(n as i32).to_be_bytes())
288 }
289 i64::MIN..=-2147483649 => {
290 writer.write_all(&[0xd3])?;
292 writer.write_all(&n.to_be_bytes())
293 }
294 0..=127 => {
295 writer.write_all(&[n as u8])
297 }
298 128..=255 => {
299 writer.write_all(&[0xcc, n as u8])
301 }
302 256..=65535 => {
303 writer.write_all(&[0xcd])?;
305 writer.write_all(&(n as u16).to_be_bytes())
306 }
307 65536..=4294967295 => {
308 writer.write_all(&[0xce])?;
310 writer.write_all(&(n as u32).to_be_bytes())
311 }
312 4294967296..=i64::MAX => {
313 writer.write_all(&[0xcf])?;
315 writer.write_all(&(n as u64).to_be_bytes())
316 }
317 }
318}
319
320fn write_map_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
321 match len {
322 0..=15 => {
323 writer.write_all(&[(0x80 | len as u8)])
325 }
326 16..=65535 => {
327 writer.write_all(&[0xde])?;
329 writer.write_all(&(len as u16).to_be_bytes())
330 }
331 _ => {
332 writer.write_all(&[0xdf])?;
334 writer.write_all(&(len as u32).to_be_bytes())
335 }
336 }
337}