1use std::io::{Cursor, Read, Write};
40
41use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
42use serde::{de::DeserializeOwned, Serialize};
43
44use crate::error::{IoError, Result};
45
46const NIL: u8 = 0xc0;
50
51const FALSE: u8 = 0xc2;
53const TRUE: u8 = 0xc3;
54
55const FLOAT32: u8 = 0xca;
57const FLOAT64: u8 = 0xcb;
58
59const UINT8: u8 = 0xcc;
61const UINT16: u8 = 0xcd;
62const UINT32: u8 = 0xce;
63const UINT64: u8 = 0xcf;
64
65const INT8: u8 = 0xd0;
67const INT16: u8 = 0xd1;
68const INT32: u8 = 0xd2;
69const INT64: u8 = 0xd3;
70
71const FIXEXT1: u8 = 0xd4;
73const FIXEXT2: u8 = 0xd5;
74const FIXEXT4: u8 = 0xd6;
75const FIXEXT8: u8 = 0xd7;
76const FIXEXT16: u8 = 0xd8;
77
78const STR8: u8 = 0xd9;
80const STR16: u8 = 0xda;
81const STR32: u8 = 0xdb;
82
83const ARRAY16: u8 = 0xdc;
85const ARRAY32: u8 = 0xdd;
86
87const MAP16: u8 = 0xde;
89const MAP32: u8 = 0xdf;
90
91const BIN8: u8 = 0xc4;
93const BIN16: u8 = 0xc5;
94const BIN32: u8 = 0xc6;
95
96const EXT8: u8 = 0xc7;
98const EXT16: u8 = 0xc8;
99const EXT32: u8 = 0xc9;
100
101const FIXINT_POS_MASK: u8 = 0x7f; const FIXINT_NEG_MASK: u8 = 0xe0; const FIXSTR_MASK: u8 = 0xa0; const FIXARRAY_MASK: u8 = 0x90; const FIXMAP_MASK: u8 = 0x80; #[derive(Debug, Clone, PartialEq)]
114pub enum MsgpackValue {
115 Nil,
117 Bool(bool),
119 Int(i64),
121 UInt(u64),
123 Float(f64),
125 Str(String),
127 Bin(Vec<u8>),
129 Array(Vec<MsgpackValue>),
131 Map(Vec<(MsgpackValue, MsgpackValue)>),
133 Ext(i8, Vec<u8>),
135}
136
137pub fn encode(value: &MsgpackValue) -> Vec<u8> {
141 let mut buf = Vec::new();
142 let _ = encode_to(&mut buf, value);
144 buf
145}
146
147pub fn write_msgpack(writer: &mut dyn Write, value: &MsgpackValue) -> Result<usize> {
151 encode_to(writer, value)
152}
153
154fn encode_to(w: &mut dyn Write, value: &MsgpackValue) -> Result<usize> {
155 match value {
156 MsgpackValue::Nil => {
157 w.write_u8(NIL).map_err(IoError::Io)?;
158 Ok(1)
159 }
160 MsgpackValue::Bool(b) => {
161 w.write_u8(if *b { TRUE } else { FALSE })
162 .map_err(IoError::Io)?;
163 Ok(1)
164 }
165 MsgpackValue::Int(i) => encode_int(w, *i),
166 MsgpackValue::UInt(u) => encode_uint(w, *u),
167 MsgpackValue::Float(f) => {
168 w.write_u8(FLOAT64).map_err(IoError::Io)?;
169 w.write_f64::<BigEndian>(*f).map_err(IoError::Io)?;
170 Ok(9)
171 }
172 MsgpackValue::Str(s) => encode_str(w, s),
173 MsgpackValue::Bin(b) => encode_bin(w, b),
174 MsgpackValue::Array(items) => encode_array(w, items),
175 MsgpackValue::Map(entries) => encode_map(w, entries),
176 MsgpackValue::Ext(type_code, data) => encode_ext(w, *type_code, data),
177 }
178}
179
180fn encode_int(w: &mut dyn Write, i: i64) -> Result<usize> {
181 if (0..=127).contains(&i) {
183 w.write_u8(i as u8).map_err(IoError::Io)?;
184 return Ok(1);
185 }
186 if (-32..0).contains(&i) {
188 w.write_u8(i as i8 as u8).map_err(IoError::Io)?;
189 return Ok(1);
190 }
191 if i >= i8::MIN as i64 && i <= i8::MAX as i64 {
192 w.write_u8(INT8).map_err(IoError::Io)?;
193 w.write_i8(i as i8).map_err(IoError::Io)?;
194 return Ok(2);
195 }
196 if i >= i16::MIN as i64 && i <= i16::MAX as i64 {
197 w.write_u8(INT16).map_err(IoError::Io)?;
198 w.write_i16::<BigEndian>(i as i16).map_err(IoError::Io)?;
199 return Ok(3);
200 }
201 if i >= i32::MIN as i64 && i <= i32::MAX as i64 {
202 w.write_u8(INT32).map_err(IoError::Io)?;
203 w.write_i32::<BigEndian>(i as i32).map_err(IoError::Io)?;
204 return Ok(5);
205 }
206 w.write_u8(INT64).map_err(IoError::Io)?;
207 w.write_i64::<BigEndian>(i).map_err(IoError::Io)?;
208 Ok(9)
209}
210
211fn encode_uint(w: &mut dyn Write, u: u64) -> Result<usize> {
212 if u <= 127 {
213 w.write_u8(u as u8).map_err(IoError::Io)?;
214 return Ok(1);
215 }
216 if u <= u8::MAX as u64 {
217 w.write_u8(UINT8).map_err(IoError::Io)?;
218 w.write_u8(u as u8).map_err(IoError::Io)?;
219 return Ok(2);
220 }
221 if u <= u16::MAX as u64 {
222 w.write_u8(UINT16).map_err(IoError::Io)?;
223 w.write_u16::<BigEndian>(u as u16).map_err(IoError::Io)?;
224 return Ok(3);
225 }
226 if u <= u32::MAX as u64 {
227 w.write_u8(UINT32).map_err(IoError::Io)?;
228 w.write_u32::<BigEndian>(u as u32).map_err(IoError::Io)?;
229 return Ok(5);
230 }
231 w.write_u8(UINT64).map_err(IoError::Io)?;
232 w.write_u64::<BigEndian>(u).map_err(IoError::Io)?;
233 Ok(9)
234}
235
236fn encode_str(w: &mut dyn Write, s: &str) -> Result<usize> {
237 let bytes = s.as_bytes();
238 let len = bytes.len();
239 let header_size = if len <= 31 {
240 w.write_u8(FIXSTR_MASK | len as u8).map_err(IoError::Io)?;
241 1
242 } else if len <= u8::MAX as usize {
243 w.write_u8(STR8).map_err(IoError::Io)?;
244 w.write_u8(len as u8).map_err(IoError::Io)?;
245 2
246 } else if len <= u16::MAX as usize {
247 w.write_u8(STR16).map_err(IoError::Io)?;
248 w.write_u16::<BigEndian>(len as u16).map_err(IoError::Io)?;
249 3
250 } else if len <= u32::MAX as usize {
251 w.write_u8(STR32).map_err(IoError::Io)?;
252 w.write_u32::<BigEndian>(len as u32).map_err(IoError::Io)?;
253 5
254 } else {
255 return Err(IoError::SerializationError(
256 "string too large for MessagePack (> 4 GiB)".to_string(),
257 ));
258 };
259 w.write_all(bytes).map_err(IoError::Io)?;
260 Ok(header_size + len)
261}
262
263fn encode_bin(w: &mut dyn Write, data: &[u8]) -> Result<usize> {
264 let len = data.len();
265 let header_size = if len <= u8::MAX as usize {
266 w.write_u8(BIN8).map_err(IoError::Io)?;
267 w.write_u8(len as u8).map_err(IoError::Io)?;
268 2
269 } else if len <= u16::MAX as usize {
270 w.write_u8(BIN16).map_err(IoError::Io)?;
271 w.write_u16::<BigEndian>(len as u16).map_err(IoError::Io)?;
272 3
273 } else if len <= u32::MAX as usize {
274 w.write_u8(BIN32).map_err(IoError::Io)?;
275 w.write_u32::<BigEndian>(len as u32).map_err(IoError::Io)?;
276 5
277 } else {
278 return Err(IoError::SerializationError(
279 "binary data too large for MessagePack (> 4 GiB)".to_string(),
280 ));
281 };
282 w.write_all(data).map_err(IoError::Io)?;
283 Ok(header_size + len)
284}
285
286fn encode_array(w: &mut dyn Write, items: &[MsgpackValue]) -> Result<usize> {
287 let n = items.len();
288 let header_size = if n <= 15 {
289 w.write_u8(FIXARRAY_MASK | n as u8).map_err(IoError::Io)?;
290 1
291 } else if n <= u16::MAX as usize {
292 w.write_u8(ARRAY16).map_err(IoError::Io)?;
293 w.write_u16::<BigEndian>(n as u16).map_err(IoError::Io)?;
294 3
295 } else if n <= u32::MAX as usize {
296 w.write_u8(ARRAY32).map_err(IoError::Io)?;
297 w.write_u32::<BigEndian>(n as u32).map_err(IoError::Io)?;
298 5
299 } else {
300 return Err(IoError::SerializationError(
301 "array too large for MessagePack (> 4 GiB elements)".to_string(),
302 ));
303 };
304 let mut total = header_size;
305 for item in items {
306 total += encode_to(w, item)?;
307 }
308 Ok(total)
309}
310
311fn encode_map(w: &mut dyn Write, entries: &[(MsgpackValue, MsgpackValue)]) -> Result<usize> {
312 let n = entries.len();
313 let header_size = if n <= 15 {
314 w.write_u8(FIXMAP_MASK | n as u8).map_err(IoError::Io)?;
315 1
316 } else if n <= u16::MAX as usize {
317 w.write_u8(MAP16).map_err(IoError::Io)?;
318 w.write_u16::<BigEndian>(n as u16).map_err(IoError::Io)?;
319 3
320 } else if n <= u32::MAX as usize {
321 w.write_u8(MAP32).map_err(IoError::Io)?;
322 w.write_u32::<BigEndian>(n as u32).map_err(IoError::Io)?;
323 5
324 } else {
325 return Err(IoError::SerializationError(
326 "map too large for MessagePack (> 4 GiB entries)".to_string(),
327 ));
328 };
329 let mut total = header_size;
330 for (k, v) in entries {
331 total += encode_to(w, k)?;
332 total += encode_to(w, v)?;
333 }
334 Ok(total)
335}
336
337fn encode_ext(w: &mut dyn Write, type_code: i8, data: &[u8]) -> Result<usize> {
338 let len = data.len();
339 let header_size = match len {
340 1 => {
341 w.write_u8(FIXEXT1).map_err(IoError::Io)?;
342 w.write_i8(type_code).map_err(IoError::Io)?;
343 2
344 }
345 2 => {
346 w.write_u8(FIXEXT2).map_err(IoError::Io)?;
347 w.write_i8(type_code).map_err(IoError::Io)?;
348 2
349 }
350 4 => {
351 w.write_u8(FIXEXT4).map_err(IoError::Io)?;
352 w.write_i8(type_code).map_err(IoError::Io)?;
353 2
354 }
355 8 => {
356 w.write_u8(FIXEXT8).map_err(IoError::Io)?;
357 w.write_i8(type_code).map_err(IoError::Io)?;
358 2
359 }
360 16 => {
361 w.write_u8(FIXEXT16).map_err(IoError::Io)?;
362 w.write_i8(type_code).map_err(IoError::Io)?;
363 2
364 }
365 l if l <= u8::MAX as usize => {
366 w.write_u8(EXT8).map_err(IoError::Io)?;
367 w.write_u8(l as u8).map_err(IoError::Io)?;
368 w.write_i8(type_code).map_err(IoError::Io)?;
369 3
370 }
371 l if l <= u16::MAX as usize => {
372 w.write_u8(EXT16).map_err(IoError::Io)?;
373 w.write_u16::<BigEndian>(l as u16).map_err(IoError::Io)?;
374 w.write_i8(type_code).map_err(IoError::Io)?;
375 4
376 }
377 l if l <= u32::MAX as usize => {
378 w.write_u8(EXT32).map_err(IoError::Io)?;
379 w.write_u32::<BigEndian>(l as u32).map_err(IoError::Io)?;
380 w.write_i8(type_code).map_err(IoError::Io)?;
381 6
382 }
383 _ => {
384 return Err(IoError::SerializationError(
385 "ext data too large for MessagePack (> 4 GiB)".to_string(),
386 ));
387 }
388 };
389 w.write_all(data).map_err(IoError::Io)?;
390 Ok(header_size + len)
391}
392
393pub fn decode(bytes: &[u8]) -> Result<MsgpackValue> {
399 let mut cursor = Cursor::new(bytes);
400 let value = decode_from(&mut cursor)?;
401 Ok(value)
402}
403
404pub fn read_msgpack(reader: &mut dyn Read) -> Result<MsgpackValue> {
406 let mut buf = Vec::new();
407 reader.read_to_end(&mut buf).map_err(IoError::Io)?;
408 decode(&buf)
409}
410
411fn decode_from(cur: &mut Cursor<&[u8]>) -> Result<MsgpackValue> {
412 let byte = read_byte(cur)?;
413
414 match byte {
415 NIL => Ok(MsgpackValue::Nil),
417
418 FALSE => Ok(MsgpackValue::Bool(false)),
420 TRUE => Ok(MsgpackValue::Bool(true)),
421
422 FLOAT32 => {
424 let f = cur
425 .read_f32::<BigEndian>()
426 .map_err(|e| IoError::FormatError(format!("msgpack float32 read: {e}")))?;
427 Ok(MsgpackValue::Float(f as f64))
428 }
429 FLOAT64 => {
430 let f = cur
431 .read_f64::<BigEndian>()
432 .map_err(|e| IoError::FormatError(format!("msgpack float64 read: {e}")))?;
433 Ok(MsgpackValue::Float(f))
434 }
435
436 UINT8 => {
438 let v = read_byte(cur)? as u64;
439 Ok(MsgpackValue::UInt(v))
440 }
441 UINT16 => {
442 let v = cur
443 .read_u16::<BigEndian>()
444 .map_err(|e| IoError::FormatError(format!("msgpack uint16 read: {e}")))?
445 as u64;
446 Ok(MsgpackValue::UInt(v))
447 }
448 UINT32 => {
449 let v = cur
450 .read_u32::<BigEndian>()
451 .map_err(|e| IoError::FormatError(format!("msgpack uint32 read: {e}")))?
452 as u64;
453 Ok(MsgpackValue::UInt(v))
454 }
455 UINT64 => {
456 let v = cur
457 .read_u64::<BigEndian>()
458 .map_err(|e| IoError::FormatError(format!("msgpack uint64 read: {e}")))?;
459 Ok(MsgpackValue::UInt(v))
460 }
461
462 INT8 => {
464 let v = cur
465 .read_i8()
466 .map_err(|e| IoError::FormatError(format!("msgpack int8 read: {e}")))?
467 as i64;
468 Ok(MsgpackValue::Int(v))
469 }
470 INT16 => {
471 let v = cur
472 .read_i16::<BigEndian>()
473 .map_err(|e| IoError::FormatError(format!("msgpack int16 read: {e}")))?
474 as i64;
475 Ok(MsgpackValue::Int(v))
476 }
477 INT32 => {
478 let v = cur
479 .read_i32::<BigEndian>()
480 .map_err(|e| IoError::FormatError(format!("msgpack int32 read: {e}")))?
481 as i64;
482 Ok(MsgpackValue::Int(v))
483 }
484 INT64 => {
485 let v = cur
486 .read_i64::<BigEndian>()
487 .map_err(|e| IoError::FormatError(format!("msgpack int64 read: {e}")))?;
488 Ok(MsgpackValue::Int(v))
489 }
490
491 STR8 => {
493 let len = read_byte(cur)? as usize;
494 Ok(MsgpackValue::Str(read_utf8(cur, len)?))
495 }
496 STR16 => {
497 let len = cur
498 .read_u16::<BigEndian>()
499 .map_err(|e| IoError::FormatError(format!("msgpack str16 len: {e}")))?
500 as usize;
501 Ok(MsgpackValue::Str(read_utf8(cur, len)?))
502 }
503 STR32 => {
504 let len = cur
505 .read_u32::<BigEndian>()
506 .map_err(|e| IoError::FormatError(format!("msgpack str32 len: {e}")))?
507 as usize;
508 Ok(MsgpackValue::Str(read_utf8(cur, len)?))
509 }
510
511 BIN8 => {
513 let len = read_byte(cur)? as usize;
514 Ok(MsgpackValue::Bin(read_bytes(cur, len)?))
515 }
516 BIN16 => {
517 let len = cur
518 .read_u16::<BigEndian>()
519 .map_err(|e| IoError::FormatError(format!("msgpack bin16 len: {e}")))?
520 as usize;
521 Ok(MsgpackValue::Bin(read_bytes(cur, len)?))
522 }
523 BIN32 => {
524 let len = cur
525 .read_u32::<BigEndian>()
526 .map_err(|e| IoError::FormatError(format!("msgpack bin32 len: {e}")))?
527 as usize;
528 Ok(MsgpackValue::Bin(read_bytes(cur, len)?))
529 }
530
531 ARRAY16 => {
533 let n = cur
534 .read_u16::<BigEndian>()
535 .map_err(|e| IoError::FormatError(format!("msgpack array16 len: {e}")))?
536 as usize;
537 read_array(cur, n)
538 }
539 ARRAY32 => {
540 let n = cur
541 .read_u32::<BigEndian>()
542 .map_err(|e| IoError::FormatError(format!("msgpack array32 len: {e}")))?
543 as usize;
544 read_array(cur, n)
545 }
546
547 MAP16 => {
549 let n = cur
550 .read_u16::<BigEndian>()
551 .map_err(|e| IoError::FormatError(format!("msgpack map16 len: {e}")))?
552 as usize;
553 read_map(cur, n)
554 }
555 MAP32 => {
556 let n = cur
557 .read_u32::<BigEndian>()
558 .map_err(|e| IoError::FormatError(format!("msgpack map32 len: {e}")))?
559 as usize;
560 read_map(cur, n)
561 }
562
563 FIXEXT1 => {
565 let tc = cur
566 .read_i8()
567 .map_err(|e| IoError::FormatError(format!("msgpack fixext1 type: {e}")))?;
568 Ok(MsgpackValue::Ext(tc, read_bytes(cur, 1)?))
569 }
570 FIXEXT2 => {
571 let tc = cur
572 .read_i8()
573 .map_err(|e| IoError::FormatError(format!("msgpack fixext2 type: {e}")))?;
574 Ok(MsgpackValue::Ext(tc, read_bytes(cur, 2)?))
575 }
576 FIXEXT4 => {
577 let tc = cur
578 .read_i8()
579 .map_err(|e| IoError::FormatError(format!("msgpack fixext4 type: {e}")))?;
580 Ok(MsgpackValue::Ext(tc, read_bytes(cur, 4)?))
581 }
582 FIXEXT8 => {
583 let tc = cur
584 .read_i8()
585 .map_err(|e| IoError::FormatError(format!("msgpack fixext8 type: {e}")))?;
586 Ok(MsgpackValue::Ext(tc, read_bytes(cur, 8)?))
587 }
588 FIXEXT16 => {
589 let tc = cur
590 .read_i8()
591 .map_err(|e| IoError::FormatError(format!("msgpack fixext16 type: {e}")))?;
592 Ok(MsgpackValue::Ext(tc, read_bytes(cur, 16)?))
593 }
594
595 EXT8 => {
597 let len = read_byte(cur)? as usize;
598 let tc = cur
599 .read_i8()
600 .map_err(|e| IoError::FormatError(format!("msgpack ext8 type: {e}")))?;
601 Ok(MsgpackValue::Ext(tc, read_bytes(cur, len)?))
602 }
603 EXT16 => {
604 let len = cur
605 .read_u16::<BigEndian>()
606 .map_err(|e| IoError::FormatError(format!("msgpack ext16 len: {e}")))?
607 as usize;
608 let tc = cur
609 .read_i8()
610 .map_err(|e| IoError::FormatError(format!("msgpack ext16 type: {e}")))?;
611 Ok(MsgpackValue::Ext(tc, read_bytes(cur, len)?))
612 }
613 EXT32 => {
614 let len = cur
615 .read_u32::<BigEndian>()
616 .map_err(|e| IoError::FormatError(format!("msgpack ext32 len: {e}")))?
617 as usize;
618 let tc = cur
619 .read_i8()
620 .map_err(|e| IoError::FormatError(format!("msgpack ext32 type: {e}")))?;
621 Ok(MsgpackValue::Ext(tc, read_bytes(cur, len)?))
622 }
623
624 b if b & 0x80 == 0 => Ok(MsgpackValue::Int((b & FIXINT_POS_MASK) as i64)),
626
627 b if b & 0xe0 == FIXINT_NEG_MASK => {
629 let signed = (b as i8) as i64;
631 Ok(MsgpackValue::Int(signed))
632 }
633
634 b if b & 0xe0 == FIXSTR_MASK => {
636 let len = (b & 0x1f) as usize;
637 Ok(MsgpackValue::Str(read_utf8(cur, len)?))
638 }
639
640 b if b & 0xf0 == FIXARRAY_MASK => {
642 let n = (b & 0x0f) as usize;
643 read_array(cur, n)
644 }
645
646 b if b & 0xf0 == FIXMAP_MASK => {
648 let n = (b & 0x0f) as usize;
649 read_map(cur, n)
650 }
651
652 other => Err(IoError::FormatError(format!(
654 "unknown MessagePack format byte: {other:#04x}"
655 ))),
656 }
657}
658
659fn read_byte(cur: &mut Cursor<&[u8]>) -> Result<u8> {
662 cur.read_u8()
663 .map_err(|e| IoError::FormatError(format!("unexpected end of msgpack data: {e}")))
664}
665
666fn read_bytes(cur: &mut Cursor<&[u8]>, len: usize) -> Result<Vec<u8>> {
667 let mut buf = vec![0u8; len];
668 cur.read_exact(&mut buf)
669 .map_err(|e| IoError::FormatError(format!("truncated msgpack data ({len} bytes): {e}")))?;
670 Ok(buf)
671}
672
673fn read_utf8(cur: &mut Cursor<&[u8]>, len: usize) -> Result<String> {
674 let bytes = read_bytes(cur, len)?;
675 String::from_utf8(bytes)
676 .map_err(|e| IoError::FormatError(format!("invalid UTF-8 in msgpack str: {e}")))
677}
678
679fn read_array(cur: &mut Cursor<&[u8]>, n: usize) -> Result<MsgpackValue> {
680 let mut items = Vec::with_capacity(n.min(1024));
681 for _ in 0..n {
682 items.push(decode_from(cur)?);
683 }
684 Ok(MsgpackValue::Array(items))
685}
686
687fn read_map(cur: &mut Cursor<&[u8]>, n: usize) -> Result<MsgpackValue> {
688 let mut entries = Vec::with_capacity(n.min(1024));
689 for _ in 0..n {
690 let k = decode_from(cur)?;
691 let v = decode_from(cur)?;
692 entries.push((k, v));
693 }
694 Ok(MsgpackValue::Map(entries))
695}
696
697pub fn to_msgpack<T: Serialize>(value: &T) -> Result<Vec<u8>> {
704 let json_val = serde_json::to_value(value)
705 .map_err(|e| IoError::SerializationError(format!("to_msgpack serde_json: {e}")))?;
706 let mp_val = json_value_to_msgpack(&json_val);
707 Ok(encode(&mp_val))
708}
709
710pub fn from_msgpack<T: DeserializeOwned>(bytes: &[u8]) -> Result<T> {
715 let mp_val = decode(bytes)?;
716 let json_val = msgpack_to_json_value(&mp_val)?;
717 serde_json::from_value(json_val)
718 .map_err(|e| IoError::DeserializationError(format!("from_msgpack serde_json: {e}")))
719}
720
721pub fn json_value_to_msgpack(v: &serde_json::Value) -> MsgpackValue {
725 match v {
726 serde_json::Value::Null => MsgpackValue::Nil,
727 serde_json::Value::Bool(b) => MsgpackValue::Bool(*b),
728 serde_json::Value::Number(n) => {
729 if let Some(i) = n.as_i64() {
730 MsgpackValue::Int(i)
731 } else if let Some(u) = n.as_u64() {
732 MsgpackValue::UInt(u)
733 } else {
734 MsgpackValue::Float(n.as_f64().unwrap_or(f64::NAN))
735 }
736 }
737 serde_json::Value::String(s) => MsgpackValue::Str(s.clone()),
738 serde_json::Value::Array(arr) => {
739 MsgpackValue::Array(arr.iter().map(json_value_to_msgpack).collect())
740 }
741 serde_json::Value::Object(obj) => MsgpackValue::Map(
742 obj.iter()
743 .map(|(k, v)| (MsgpackValue::Str(k.clone()), json_value_to_msgpack(v)))
744 .collect(),
745 ),
746 }
747}
748
749pub fn msgpack_to_json_value(v: &MsgpackValue) -> Result<serde_json::Value> {
756 match v {
757 MsgpackValue::Nil => Ok(serde_json::Value::Null),
758 MsgpackValue::Bool(b) => Ok(serde_json::Value::Bool(*b)),
759 MsgpackValue::Int(i) => Ok(serde_json::json!(*i)),
760 MsgpackValue::UInt(u) => {
761 if *u <= i64::MAX as u64 {
762 Ok(serde_json::json!(*u as i64))
763 } else {
764 Ok(serde_json::json!(*u as f64))
765 }
766 }
767 MsgpackValue::Float(f) => {
768 let n = serde_json::Number::from_f64(*f).ok_or_else(|| {
769 IoError::ConversionError(format!("non-finite float cannot be JSON: {f}"))
770 })?;
771 Ok(serde_json::Value::Number(n))
772 }
773 MsgpackValue::Str(s) => Ok(serde_json::Value::String(s.clone())),
774 MsgpackValue::Bin(b) => {
775 let arr: Vec<serde_json::Value> =
777 b.iter().map(|&byte| serde_json::json!(byte)).collect();
778 Ok(serde_json::Value::Array(arr))
779 }
780 MsgpackValue::Array(items) => {
781 let arr: Result<Vec<serde_json::Value>> =
782 items.iter().map(msgpack_to_json_value).collect();
783 Ok(serde_json::Value::Array(arr?))
784 }
785 MsgpackValue::Map(entries) => {
786 let mut obj = serde_json::Map::new();
787 for (k, v) in entries {
788 let key = match k {
789 MsgpackValue::Str(s) => s.clone(),
790 other => {
791 format!("{other:?}")
793 }
794 };
795 obj.insert(key, msgpack_to_json_value(v)?);
796 }
797 Ok(serde_json::Value::Object(obj))
798 }
799 MsgpackValue::Ext(type_code, data) => {
800 let bytes: Vec<serde_json::Value> =
802 data.iter().map(|&b| serde_json::json!(b)).collect();
803 Ok(serde_json::json!({
804 "__msgpack_ext_type": *type_code as i64,
805 "data": bytes,
806 }))
807 }
808 }
809}
810
811#[cfg(test)]
814mod tests {
815 use super::*;
816
817 fn rt(v: &MsgpackValue) -> MsgpackValue {
820 let bytes = encode(v);
821 decode(&bytes).expect("decode")
822 }
823
824 #[test]
827 fn test_nil_roundtrip() {
828 assert_eq!(rt(&MsgpackValue::Nil), MsgpackValue::Nil);
829 }
830
831 #[test]
832 fn test_bool_roundtrip() {
833 assert_eq!(rt(&MsgpackValue::Bool(true)), MsgpackValue::Bool(true));
834 assert_eq!(rt(&MsgpackValue::Bool(false)), MsgpackValue::Bool(false));
835 }
836
837 #[test]
840 fn test_positive_fixint_boundaries() {
841 for i in [0i64, 1, 63, 127] {
842 let v = MsgpackValue::Int(i);
843 assert_eq!(rt(&v), v, "fixint {i}");
844 assert_eq!(encode(&v).len(), 1, "fixint len {i}");
846 }
847 }
848
849 #[test]
852 fn test_negative_fixint_boundaries() {
853 for i in [-1i64, -16, -32] {
854 let v = MsgpackValue::Int(i);
855 assert_eq!(rt(&v), v, "neg fixint {i}");
856 assert_eq!(encode(&v).len(), 1, "neg fixint len {i}");
857 }
858 }
859
860 #[test]
863 fn test_int8_roundtrip() {
864 for i in [i8::MIN as i64, i8::MAX as i64, -33i64, 128] {
865 let v = MsgpackValue::Int(i);
866 assert_eq!(rt(&v), v, "int8 {i}");
867 }
868 }
869
870 #[test]
871 fn test_int16_roundtrip() {
872 for i in [i16::MIN as i64, i16::MAX as i64, 256i64, -300] {
873 let v = MsgpackValue::Int(i);
874 assert_eq!(rt(&v), v, "int16 {i}");
875 }
876 }
877
878 #[test]
879 fn test_int32_roundtrip() {
880 for i in [i32::MIN as i64, i32::MAX as i64, 70_000i64, -70_000] {
881 let v = MsgpackValue::Int(i);
882 assert_eq!(rt(&v), v, "int32 {i}");
883 }
884 }
885
886 #[test]
887 fn test_int64_roundtrip() {
888 for i in [i64::MIN, i64::MAX, i64::from(i32::MAX) + 1] {
889 let v = MsgpackValue::Int(i);
890 assert_eq!(rt(&v), v, "int64 {i}");
891 }
892 }
893
894 #[test]
897 fn test_uint8_roundtrip() {
898 let v = MsgpackValue::UInt(200);
899 assert_eq!(rt(&v), v);
900 assert_eq!(encode(&v).len(), 2); }
902
903 #[test]
904 fn test_uint16_roundtrip() {
905 let v = MsgpackValue::UInt(1000);
906 assert_eq!(rt(&v), v);
907 assert_eq!(encode(&v).len(), 3);
908 }
909
910 #[test]
911 fn test_uint32_roundtrip() {
912 let v = MsgpackValue::UInt(100_000);
913 assert_eq!(rt(&v), v);
914 assert_eq!(encode(&v).len(), 5);
915 }
916
917 #[test]
918 fn test_uint64_roundtrip() {
919 let v = MsgpackValue::UInt(u64::MAX);
920 assert_eq!(rt(&v), v);
921 assert_eq!(encode(&v).len(), 9);
922 }
923
924 #[test]
927 fn test_float64_roundtrip() {
928 for f in [
929 0.0_f64,
930 1.0,
931 -1.0,
932 f64::MAX,
933 f64::MIN_POSITIVE,
934 std::f64::consts::PI,
935 ] {
936 let v = MsgpackValue::Float(f);
937 assert_eq!(rt(&v), v, "float64 {f}");
938 }
939 }
940
941 #[test]
944 fn test_fixstr_roundtrip() {
945 let v = MsgpackValue::Str("hello".into());
946 assert_eq!(rt(&v), v);
947 assert_eq!(encode(&v).len(), 6);
949 }
950
951 #[test]
952 fn test_str8_roundtrip() {
953 let s: String = "x".repeat(32);
955 let v = MsgpackValue::Str(s.clone());
956 let encoded = encode(&v);
957 assert_eq!(encoded[0], STR8);
958 assert_eq!(rt(&v), v);
959 }
960
961 #[test]
962 fn test_str16_roundtrip() {
963 let s: String = "y".repeat(300);
964 let v = MsgpackValue::Str(s);
965 let encoded = encode(&v);
966 assert_eq!(encoded[0], STR16);
967 assert_eq!(rt(&v), v);
968 }
969
970 #[test]
971 fn test_empty_string() {
972 let v = MsgpackValue::Str(String::new());
973 assert_eq!(rt(&v), v);
974 }
975
976 #[test]
979 fn test_bin8_roundtrip() {
980 let v = MsgpackValue::Bin(vec![0x00, 0xff, 0x42]);
981 assert_eq!(rt(&v), v);
982 assert_eq!(encode(&v)[0], BIN8);
983 }
984
985 #[test]
986 fn test_bin16_roundtrip() {
987 let v = MsgpackValue::Bin(vec![0u8; 256]);
988 let encoded = encode(&v);
989 assert_eq!(encoded[0], BIN16);
990 assert_eq!(rt(&v), v);
991 }
992
993 #[test]
994 fn test_bin32_roundtrip() {
995 let v = MsgpackValue::Bin(vec![1u8; 65536]);
996 let encoded = encode(&v);
997 assert_eq!(encoded[0], BIN32);
998 assert_eq!(rt(&v), v);
999 }
1000
1001 #[test]
1004 fn test_fixarray_roundtrip() {
1005 let v = MsgpackValue::Array(vec![
1006 MsgpackValue::Int(1),
1007 MsgpackValue::Str("two".into()),
1008 MsgpackValue::Bool(true),
1009 ]);
1010 assert_eq!(rt(&v), v);
1011 }
1012
1013 #[test]
1014 fn test_array16_roundtrip() {
1015 let items: Vec<MsgpackValue> = (0..16).map(|i| MsgpackValue::Int(i)).collect();
1016 let v = MsgpackValue::Array(items);
1017 let encoded = encode(&v);
1018 assert_eq!(encoded[0], ARRAY16);
1019 assert_eq!(rt(&v), v);
1020 }
1021
1022 #[test]
1023 fn test_nested_array() {
1024 let inner = MsgpackValue::Array(vec![MsgpackValue::Int(99)]);
1025 let outer = MsgpackValue::Array(vec![inner, MsgpackValue::Nil]);
1026 assert_eq!(rt(&outer), outer);
1027 }
1028
1029 #[test]
1032 fn test_fixmap_roundtrip() {
1033 let v = MsgpackValue::Map(vec![
1034 (MsgpackValue::Str("a".into()), MsgpackValue::Int(1)),
1035 (MsgpackValue::Str("b".into()), MsgpackValue::Bool(false)),
1036 ]);
1037 assert_eq!(rt(&v), v);
1038 }
1039
1040 #[test]
1041 fn test_map16_roundtrip() {
1042 let entries: Vec<(MsgpackValue, MsgpackValue)> = (0..16)
1043 .map(|i| (MsgpackValue::Int(i), MsgpackValue::Int(i * 2)))
1044 .collect();
1045 let v = MsgpackValue::Map(entries);
1046 let encoded = encode(&v);
1047 assert_eq!(encoded[0], MAP16);
1048 assert_eq!(rt(&v), v);
1049 }
1050
1051 #[test]
1054 fn test_fixext1_roundtrip() {
1055 let v = MsgpackValue::Ext(42, vec![0xab]);
1056 assert_eq!(rt(&v), v);
1057 assert_eq!(encode(&v).len(), 3); }
1059
1060 #[test]
1061 fn test_fixext8_roundtrip() {
1062 let v = MsgpackValue::Ext(-1, vec![0u8; 8]);
1063 assert_eq!(rt(&v), v);
1064 }
1065
1066 #[test]
1067 fn test_ext8_roundtrip() {
1068 let v = MsgpackValue::Ext(5, vec![0xffu8; 3]);
1069 assert_eq!(rt(&v), v);
1070 assert_eq!(encode(&v)[0], EXT8);
1071 }
1072
1073 #[test]
1076 fn test_to_from_msgpack_struct() {
1077 #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)]
1078 struct Point {
1079 x: f64,
1080 y: f64,
1081 }
1082
1083 let p = Point { x: 1.5, y: -2.5 };
1084 let bytes = to_msgpack(&p).expect("serialize");
1085 let p2: Point = from_msgpack(&bytes).expect("deserialize");
1086 assert!((p.x - p2.x).abs() < 1e-10);
1087 assert!((p.y - p2.y).abs() < 1e-10);
1088 }
1089
1090 #[test]
1091 fn test_to_from_msgpack_vec() {
1092 let data = vec![1i64, 2, 3, 4, 5];
1093 let bytes = to_msgpack(&data).expect("serialize");
1094 let out: Vec<i64> = from_msgpack(&bytes).expect("deserialize");
1095 assert_eq!(data, out);
1096 }
1097
1098 #[test]
1101 fn test_write_read_msgpack() {
1102 let value = MsgpackValue::Map(vec![
1103 (MsgpackValue::Str("count".into()), MsgpackValue::Int(7)),
1104 (
1105 MsgpackValue::Str("label".into()),
1106 MsgpackValue::Str("test".into()),
1107 ),
1108 ]);
1109
1110 let mut buf = Vec::new();
1111 write_msgpack(&mut buf, &value).expect("write");
1112 let decoded = read_msgpack(&mut buf.as_slice()).expect("read");
1113 assert_eq!(value, decoded);
1114 }
1115
1116 #[test]
1119 fn test_decode_empty_input() {
1120 let result = decode(&[]);
1121 assert!(result.is_err(), "empty input should error");
1122 }
1123
1124 #[test]
1125 fn test_decode_truncated_str() {
1126 let mut bytes = Vec::new();
1128 bytes.push(FIXSTR_MASK | 5);
1129 bytes.extend_from_slice(b"abc"); let result = decode(&bytes);
1131 assert!(result.is_err(), "truncated str should error");
1132 }
1133
1134 #[test]
1135 fn test_decode_unknown_byte() {
1136 let result = decode(&[0xc1]);
1138 assert!(result.is_err(), "unknown format byte should error");
1139 }
1140}