facet_msgpack/
to_msgpack.rs1use facet_core::{Facet, ShapeExt as _};
2use facet_peek::Peek;
3use log::trace;
4use std::io::{self, Write};
5
6pub fn to_vec<T: Facet>(value: &T) -> Vec<u8> {
8 let mut buffer = Vec::new();
9 let peek = Peek::new(value);
10 serialize(peek, &mut buffer).unwrap();
11 buffer
12}
13
14fn serialize<W: Write>(peek: Peek<'_>, writer: &mut W) -> io::Result<()> {
16 match peek {
17 Peek::Value(pv) => {
18 trace!("Serializing scalar");
19 if pv.shape().is_type::<String>() {
20 let value = unsafe { pv.data().as_ref::<String>() };
21 write_str(writer, value)
22 } else if pv.shape().is_type::<u64>() {
23 let value = unsafe { pv.data().as_ref::<u64>() };
24 write_u64(writer, *value)
25 } else if pv.shape().is_type::<u32>() {
26 let value = unsafe { pv.data().as_ref::<u32>() };
27 write_u32(writer, *value)
28 } else if pv.shape().is_type::<u16>() {
29 let value = unsafe { pv.data().as_ref::<u16>() };
30 write_u16(writer, *value)
31 } else if pv.shape().is_type::<u8>() {
32 let value = unsafe { pv.data().as_ref::<u8>() };
33 write_u8(writer, *value)
34 } else if pv.shape().is_type::<i64>() {
35 let value = unsafe { pv.data().as_ref::<i64>() };
36 write_i64(writer, *value)
37 } else if pv.shape().is_type::<i32>() {
38 let value = unsafe { pv.data().as_ref::<i32>() };
39 write_i32(writer, *value)
40 } else if pv.shape().is_type::<i16>() {
41 let value = unsafe { pv.data().as_ref::<i16>() };
42 write_i16(writer, *value)
43 } else if pv.shape().is_type::<i8>() {
44 let value = unsafe { pv.data().as_ref::<i8>() };
45 write_i8(writer, *value)
46 } else {
47 todo!("Unsupported scalar type: {}", pv.shape())
48 }
49 }
50 Peek::Struct(ps) => {
51 trace!("Serializing struct");
52
53 let fields: Vec<_> = ps.fields().collect();
55 write_map_len(writer, fields.len())?;
56
57 for (name, field_peek) in fields {
59 write_str(writer, name)?;
60 serialize(field_peek, writer)?;
61 }
62 Ok(())
63 }
64 _ => {
65 todo!("Unsupported type: {:?}", peek)
66 }
67 }
68}
69
70fn write_str<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
71 let bytes = s.as_bytes();
72 let len = bytes.len();
73
74 match len {
75 0..=31 => {
76 writer.write_all(&[(0xa0 | len as u8)])?;
78 }
79 32..=255 => {
80 writer.write_all(&[0xd9, len as u8])?;
82 }
83 256..=65535 => {
84 writer.write_all(&[0xda])?;
86 writer.write_all(&(len as u16).to_be_bytes())?;
87 }
88 _ => {
89 writer.write_all(&[0xdb])?;
91 writer.write_all(&(len as u32).to_be_bytes())?;
92 }
93 }
94 writer.write_all(bytes)
95}
96
97fn write_u8<W: Write>(writer: &mut W, n: u8) -> io::Result<()> {
98 match n {
99 0..=127 => {
100 writer.write_all(&[n])
102 }
103 _ => {
104 writer.write_all(&[0xcc, n])
106 }
107 }
108}
109
110fn write_u16<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
111 match n {
112 0..=127 => {
113 writer.write_all(&[n as u8])
115 }
116 128..=255 => {
117 writer.write_all(&[0xcc, n as u8])
119 }
120 _ => {
121 writer.write_all(&[0xcd])?;
123 writer.write_all(&n.to_be_bytes())
124 }
125 }
126}
127
128fn write_u32<W: Write>(writer: &mut W, n: u32) -> io::Result<()> {
129 match n {
130 0..=127 => {
131 writer.write_all(&[n as u8])
133 }
134 128..=255 => {
135 writer.write_all(&[0xcc, n as u8])
137 }
138 256..=65535 => {
139 writer.write_all(&[0xcd])?;
141 writer.write_all(&(n as u16).to_be_bytes())
142 }
143 _ => {
144 writer.write_all(&[0xce])?;
146 writer.write_all(&n.to_be_bytes())
147 }
148 }
149}
150
151fn write_u64<W: Write>(writer: &mut W, n: u64) -> io::Result<()> {
152 match n {
153 0..=127 => {
154 writer.write_all(&[n as u8])
156 }
157 128..=255 => {
158 writer.write_all(&[0xcc, n as u8])
160 }
161 256..=65535 => {
162 writer.write_all(&[0xcd])?;
164 writer.write_all(&(n as u16).to_be_bytes())
165 }
166 65536..=4294967295 => {
167 writer.write_all(&[0xce])?;
169 writer.write_all(&(n as u32).to_be_bytes())
170 }
171 _ => {
172 writer.write_all(&[0xcf])?;
174 writer.write_all(&n.to_be_bytes())
175 }
176 }
177}
178
179fn write_i8<W: Write>(writer: &mut W, n: i8) -> io::Result<()> {
180 match n {
181 -32..=-1 => {
182 writer.write_all(&[n as u8])
184 }
185 -128..=-33 => {
186 writer.write_all(&[0xd0, n as u8])
188 }
189 0..=127 => {
190 writer.write_all(&[n as u8])
192 }
193 }
194}
195
196fn write_i16<W: Write>(writer: &mut W, n: i16) -> io::Result<()> {
197 match n {
198 -32..=-1 => {
199 writer.write_all(&[n as u8])
201 }
202 -128..=-33 => {
203 writer.write_all(&[0xd0, n as u8])
205 }
206 -32768..=-129 => {
207 writer.write_all(&[0xd1])?;
209 writer.write_all(&n.to_be_bytes())
210 }
211 0..=127 => {
212 writer.write_all(&[n as u8])
214 }
215 128..=255 => {
216 writer.write_all(&[0xcc, n as u8])
218 }
219 256..=32767 => {
220 writer.write_all(&[0xcd])?;
222 writer.write_all(&(n as u16).to_be_bytes())
223 }
224 }
225}
226
227fn write_i32<W: Write>(writer: &mut W, n: i32) -> io::Result<()> {
228 match n {
229 -32..=-1 => {
230 writer.write_all(&[n as u8])
232 }
233 -128..=-33 => {
234 writer.write_all(&[0xd0, n as u8])
236 }
237 -32768..=-129 => {
238 writer.write_all(&[0xd1])?;
240 writer.write_all(&(n as i16).to_be_bytes())
241 }
242 -2147483648..=-32769 => {
243 writer.write_all(&[0xd2])?;
245 writer.write_all(&n.to_be_bytes())
246 }
247 0..=127 => {
248 writer.write_all(&[n as u8])
250 }
251 128..=255 => {
252 writer.write_all(&[0xcc, n as u8])
254 }
255 256..=65535 => {
256 writer.write_all(&[0xcd])?;
258 writer.write_all(&(n as u16).to_be_bytes())
259 }
260 65536..=2147483647 => {
261 writer.write_all(&[0xce])?;
263 writer.write_all(&(n as u32).to_be_bytes())
264 }
265 }
266}
267
268fn write_i64<W: Write>(writer: &mut W, n: i64) -> io::Result<()> {
269 match n {
270 -32..=-1 => {
271 writer.write_all(&[n as u8])
273 }
274 -128..=-33 => {
275 writer.write_all(&[0xd0, n as u8])
277 }
278 -32768..=-129 => {
279 writer.write_all(&[0xd1])?;
281 writer.write_all(&(n as i16).to_be_bytes())
282 }
283 -2147483648..=-32769 => {
284 writer.write_all(&[0xd2])?;
286 writer.write_all(&(n as i32).to_be_bytes())
287 }
288 i64::MIN..=-2147483649 => {
289 writer.write_all(&[0xd3])?;
291 writer.write_all(&n.to_be_bytes())
292 }
293 0..=127 => {
294 writer.write_all(&[n as u8])
296 }
297 128..=255 => {
298 writer.write_all(&[0xcc, n as u8])
300 }
301 256..=65535 => {
302 writer.write_all(&[0xcd])?;
304 writer.write_all(&(n as u16).to_be_bytes())
305 }
306 65536..=4294967295 => {
307 writer.write_all(&[0xce])?;
309 writer.write_all(&(n as u32).to_be_bytes())
310 }
311 4294967296..=i64::MAX => {
312 writer.write_all(&[0xcf])?;
314 writer.write_all(&(n as u64).to_be_bytes())
315 }
316 }
317}
318
319fn write_map_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
320 match len {
321 0..=15 => {
322 writer.write_all(&[(0x80 | len as u8)])
324 }
325 16..=65535 => {
326 writer.write_all(&[0xde])?;
328 writer.write_all(&(len as u16).to_be_bytes())
329 }
330 _ => {
331 writer.write_all(&[0xdf])?;
333 writer.write_all(&(len as u32).to_be_bytes())
334 }
335 }
336}