1use std::io::{Cursor, Read};
20
21use crate::error::{IoError, Result};
22
23const FMT_NIL: u8 = 0xc0;
26const FMT_FALSE: u8 = 0xc2;
27const FMT_TRUE: u8 = 0xc3;
28const FMT_BIN8: u8 = 0xc4;
29const FMT_BIN16: u8 = 0xc5;
30const FMT_BIN32: u8 = 0xc6;
31const FMT_EXT8: u8 = 0xc7;
32const FMT_EXT16: u8 = 0xc8;
33const FMT_EXT32: u8 = 0xc9;
34const FMT_FLOAT32: u8 = 0xca;
35const FMT_FLOAT64: u8 = 0xcb;
36const FMT_UINT8: u8 = 0xcc;
37const FMT_UINT16: u8 = 0xcd;
38const FMT_UINT32: u8 = 0xce;
39const FMT_UINT64: u8 = 0xcf;
40const FMT_INT8: u8 = 0xd0;
41const FMT_INT16: u8 = 0xd1;
42const FMT_INT32: u8 = 0xd2;
43const FMT_INT64: u8 = 0xd3;
44const FMT_FIXEXT1: u8 = 0xd4;
45const FMT_FIXEXT2: u8 = 0xd5;
46const FMT_FIXEXT4: u8 = 0xd6;
47const FMT_FIXEXT8: u8 = 0xd7;
48const FMT_FIXEXT16: u8 = 0xd8;
49const FMT_STR8: u8 = 0xd9;
50const FMT_STR16: u8 = 0xda;
51const FMT_STR32: u8 = 0xdb;
52const FMT_ARRAY16: u8 = 0xdc;
53const FMT_ARRAY32: u8 = 0xdd;
54const FMT_MAP16: u8 = 0xde;
55const FMT_MAP32: u8 = 0xdf;
56
57#[derive(Debug, Clone, PartialEq)]
61pub enum MsgPackValue {
62 Nil,
64 Bool(bool),
66 Int(i64),
68 UInt(u64),
70 Float32(f32),
72 Float64(f64),
74 Str(String),
76 Bin(Vec<u8>),
78 Array(Vec<MsgPackValue>),
80 Map(Vec<(MsgPackValue, MsgPackValue)>),
82 Ext(i8, Vec<u8>),
84}
85
86#[derive(Debug, Default)]
107pub struct MsgPackWriter {
108 buf: Vec<u8>,
109}
110
111impl MsgPackWriter {
112 pub fn new() -> Self {
114 Self { buf: Vec::new() }
115 }
116
117 pub fn into_bytes(self) -> Vec<u8> {
119 self.buf
120 }
121
122 pub fn as_bytes(&self) -> &[u8] {
124 &self.buf
125 }
126
127 pub fn write_nil(&mut self) {
129 self.buf.push(FMT_NIL);
130 }
131
132 pub fn write_bool(&mut self, v: bool) {
134 self.buf.push(if v { FMT_TRUE } else { FMT_FALSE });
135 }
136
137 pub fn write_int(&mut self, v: i64) {
139 if (0..=127).contains(&v) {
140 self.buf.push(v as u8);
141 } else if (-32..=-1).contains(&v) {
142 self.buf.push((v as i8) as u8);
143 } else if v >= 0 {
144 let u = v as u64;
145 if u <= u8::MAX as u64 {
146 self.buf.extend_from_slice(&[FMT_UINT8, u as u8]);
147 } else if u <= u16::MAX as u64 {
148 self.buf.push(FMT_UINT16);
149 self.buf.extend_from_slice(&(u as u16).to_be_bytes());
150 } else if u <= u32::MAX as u64 {
151 self.buf.push(FMT_UINT32);
152 self.buf.extend_from_slice(&(u as u32).to_be_bytes());
153 } else {
154 self.buf.push(FMT_UINT64);
155 self.buf.extend_from_slice(&u.to_be_bytes());
156 }
157 } else if v >= i8::MIN as i64 {
158 self.buf.extend_from_slice(&[FMT_INT8, v as u8]);
159 } else if v >= i16::MIN as i64 {
160 self.buf.push(FMT_INT16);
161 self.buf.extend_from_slice(&(v as i16).to_be_bytes());
162 } else if v >= i32::MIN as i64 {
163 self.buf.push(FMT_INT32);
164 self.buf.extend_from_slice(&(v as i32).to_be_bytes());
165 } else {
166 self.buf.push(FMT_INT64);
167 self.buf.extend_from_slice(&v.to_be_bytes());
168 }
169 }
170
171 pub fn write_uint(&mut self, v: u64) {
173 if v <= 127 {
174 self.buf.push(v as u8);
175 } else if v <= u8::MAX as u64 {
176 self.buf.extend_from_slice(&[FMT_UINT8, v as u8]);
177 } else if v <= u16::MAX as u64 {
178 self.buf.push(FMT_UINT16);
179 self.buf.extend_from_slice(&(v as u16).to_be_bytes());
180 } else if v <= u32::MAX as u64 {
181 self.buf.push(FMT_UINT32);
182 self.buf.extend_from_slice(&(v as u32).to_be_bytes());
183 } else {
184 self.buf.push(FMT_UINT64);
185 self.buf.extend_from_slice(&v.to_be_bytes());
186 }
187 }
188
189 pub fn write_float(&mut self, v: f64) {
191 self.buf.push(FMT_FLOAT64);
192 self.buf.extend_from_slice(&v.to_bits().to_be_bytes());
193 }
194
195 pub fn write_float32(&mut self, v: f32) {
197 self.buf.push(FMT_FLOAT32);
198 self.buf.extend_from_slice(&v.to_bits().to_be_bytes());
199 }
200
201 pub fn write_str(&mut self, s: &str) {
203 let bytes = s.as_bytes();
204 let n = bytes.len();
205 if n <= 31 {
206 self.buf.push(0xa0 | (n as u8));
207 } else if n <= 255 {
208 self.buf.extend_from_slice(&[FMT_STR8, n as u8]);
209 } else if n <= 65535 {
210 self.buf.push(FMT_STR16);
211 self.buf.extend_from_slice(&(n as u16).to_be_bytes());
212 } else {
213 self.buf.push(FMT_STR32);
214 self.buf.extend_from_slice(&(n as u32).to_be_bytes());
215 }
216 self.buf.extend_from_slice(bytes);
217 }
218
219 pub fn write_bin(&mut self, b: &[u8]) {
221 let n = b.len();
222 if n <= 255 {
223 self.buf.extend_from_slice(&[FMT_BIN8, n as u8]);
224 } else if n <= 65535 {
225 self.buf.push(FMT_BIN16);
226 self.buf.extend_from_slice(&(n as u16).to_be_bytes());
227 } else {
228 self.buf.push(FMT_BIN32);
229 self.buf.extend_from_slice(&(n as u32).to_be_bytes());
230 }
231 self.buf.extend_from_slice(b);
232 }
233
234 pub fn write_array_header(&mut self, n: usize) {
236 if n <= 15 {
237 self.buf.push(0x90 | (n as u8));
238 } else if n <= 65535 {
239 self.buf.push(FMT_ARRAY16);
240 self.buf.extend_from_slice(&(n as u16).to_be_bytes());
241 } else {
242 self.buf.push(FMT_ARRAY32);
243 self.buf.extend_from_slice(&(n as u32).to_be_bytes());
244 }
245 }
246
247 pub fn write_map_header(&mut self, n: usize) {
249 if n <= 15 {
250 self.buf.push(0x80 | (n as u8));
251 } else if n <= 65535 {
252 self.buf.push(FMT_MAP16);
253 self.buf.extend_from_slice(&(n as u16).to_be_bytes());
254 } else {
255 self.buf.push(FMT_MAP32);
256 self.buf.extend_from_slice(&(n as u32).to_be_bytes());
257 }
258 }
259
260 pub fn write_ext(&mut self, type_id: i8, data: &[u8]) {
262 let n = data.len();
263 let tid = type_id as u8;
264 match n {
265 1 => self.buf.extend_from_slice(&[FMT_FIXEXT1, tid]),
266 2 => self.buf.extend_from_slice(&[FMT_FIXEXT2, tid]),
267 4 => self.buf.extend_from_slice(&[FMT_FIXEXT4, tid]),
268 8 => self.buf.extend_from_slice(&[FMT_FIXEXT8, tid]),
269 16 => self.buf.extend_from_slice(&[FMT_FIXEXT16, tid]),
270 _ => {
271 if n <= 255 {
272 self.buf.extend_from_slice(&[FMT_EXT8, n as u8, tid]);
273 } else if n <= 65535 {
274 self.buf.push(FMT_EXT16);
275 self.buf.extend_from_slice(&(n as u16).to_be_bytes());
276 self.buf.push(tid);
277 } else {
278 self.buf.push(FMT_EXT32);
279 self.buf.extend_from_slice(&(n as u32).to_be_bytes());
280 self.buf.push(tid);
281 }
282 }
283 }
284 self.buf.extend_from_slice(data);
285 }
286
287 pub fn write_value(&mut self, value: &MsgPackValue) {
289 match value {
290 MsgPackValue::Nil => self.write_nil(),
291 MsgPackValue::Bool(b) => self.write_bool(*b),
292 MsgPackValue::Int(i) => self.write_int(*i),
293 MsgPackValue::UInt(u) => self.write_uint(*u),
294 MsgPackValue::Float32(f) => self.write_float32(*f),
295 MsgPackValue::Float64(f) => self.write_float(*f),
296 MsgPackValue::Str(s) => self.write_str(s),
297 MsgPackValue::Bin(b) => self.write_bin(b),
298 MsgPackValue::Array(arr) => {
299 self.write_array_header(arr.len());
300 for elem in arr {
301 self.write_value(elem);
302 }
303 }
304 MsgPackValue::Map(map) => {
305 self.write_map_header(map.len());
306 for (k, v) in map {
307 self.write_value(k);
308 self.write_value(v);
309 }
310 }
311 MsgPackValue::Ext(tid, data) => self.write_ext(*tid, data),
312 }
313 }
314}
315
316pub struct MsgPackReader<'a> {
322 data: &'a [u8],
323 pos: usize,
324}
325
326impl<'a> MsgPackReader<'a> {
327 pub fn new(data: &'a [u8]) -> Self {
329 Self { data, pos: 0 }
330 }
331
332 pub fn position(&self) -> usize {
334 self.pos
335 }
336
337 pub fn is_empty(&self) -> bool {
339 self.pos >= self.data.len()
340 }
341
342 fn read_bytes(&mut self, n: usize) -> Result<&'a [u8]> {
343 if self.pos + n > self.data.len() {
344 return Err(IoError::FormatError(format!(
345 "MsgPack: unexpected end of data (need {n} bytes at offset {})",
346 self.pos
347 )));
348 }
349 let slice = &self.data[self.pos..self.pos + n];
350 self.pos += n;
351 Ok(slice)
352 }
353
354 fn read_u8(&mut self) -> Result<u8> {
355 let b = self.read_bytes(1)?;
356 Ok(b[0])
357 }
358
359 fn read_u16_be(&mut self) -> Result<u16> {
360 let b = self.read_bytes(2)?;
361 Ok(u16::from_be_bytes([b[0], b[1]]))
362 }
363
364 fn read_u32_be(&mut self) -> Result<u32> {
365 let b = self.read_bytes(4)?;
366 Ok(u32::from_be_bytes([b[0], b[1], b[2], b[3]]))
367 }
368
369 fn read_u64_be(&mut self) -> Result<u64> {
370 let b = self.read_bytes(8)?;
371 Ok(u64::from_be_bytes(b.try_into().map_err(|_| {
372 IoError::FormatError("MsgPack: bad u64 bytes".into())
373 })?))
374 }
375
376 fn read_str_bytes(&mut self, n: usize) -> Result<MsgPackValue> {
377 let raw = self.read_bytes(n)?;
378 let s = std::str::from_utf8(raw)
379 .map_err(|e| IoError::FormatError(format!("MsgPack: invalid UTF-8: {e}")))?
380 .to_owned();
381 Ok(MsgPackValue::Str(s))
382 }
383
384 fn read_array_items(&mut self, n: usize) -> Result<MsgPackValue> {
385 let mut arr = Vec::with_capacity(n);
386 for _ in 0..n {
387 arr.push(self.read_value()?);
388 }
389 Ok(MsgPackValue::Array(arr))
390 }
391
392 fn read_map_items(&mut self, n: usize) -> Result<MsgPackValue> {
393 let mut map = Vec::with_capacity(n);
394 for _ in 0..n {
395 let k = self.read_value()?;
396 let v = self.read_value()?;
397 map.push((k, v));
398 }
399 Ok(MsgPackValue::Map(map))
400 }
401
402 fn read_ext_data(&mut self, n: usize) -> Result<MsgPackValue> {
403 let type_byte = self.read_u8()?;
404 let type_id = type_byte as i8;
405 let data = self.read_bytes(n)?.to_vec();
406 Ok(MsgPackValue::Ext(type_id, data))
407 }
408
409 pub fn read_value(&mut self) -> Result<MsgPackValue> {
411 let first = self.read_u8()?;
412
413 match first {
414 b if b & 0x80 == 0 => Ok(MsgPackValue::Int(b as i64)),
416 b if b & 0xf0 == 0x80 => self.read_map_items((b & 0x0f) as usize),
418 b if b & 0xf0 == 0x90 => self.read_array_items((b & 0x0f) as usize),
420 b if b & 0xe0 == 0xa0 => self.read_str_bytes((b & 0x1f) as usize),
422 b if b & 0xe0 == 0xe0 => Ok(MsgPackValue::Int((b as i8) as i64)),
424 FMT_NIL => Ok(MsgPackValue::Nil),
426 FMT_FALSE => Ok(MsgPackValue::Bool(false)),
427 FMT_TRUE => Ok(MsgPackValue::Bool(true)),
428 FMT_BIN8 => {
429 let n = self.read_u8()? as usize;
430 Ok(MsgPackValue::Bin(self.read_bytes(n)?.to_vec()))
431 }
432 FMT_BIN16 => {
433 let n = self.read_u16_be()? as usize;
434 Ok(MsgPackValue::Bin(self.read_bytes(n)?.to_vec()))
435 }
436 FMT_BIN32 => {
437 let n = self.read_u32_be()? as usize;
438 Ok(MsgPackValue::Bin(self.read_bytes(n)?.to_vec()))
439 }
440 FMT_EXT8 => {
441 let n = self.read_u8()? as usize;
442 self.read_ext_data(n)
443 }
444 FMT_EXT16 => {
445 let n = self.read_u16_be()? as usize;
446 self.read_ext_data(n)
447 }
448 FMT_EXT32 => {
449 let n = self.read_u32_be()? as usize;
450 self.read_ext_data(n)
451 }
452 FMT_FLOAT32 => {
453 let b = self.read_bytes(4)?;
454 let bits = u32::from_be_bytes([b[0], b[1], b[2], b[3]]);
455 Ok(MsgPackValue::Float32(f32::from_bits(bits)))
456 }
457 FMT_FLOAT64 => {
458 let bits = self.read_u64_be()?;
459 Ok(MsgPackValue::Float64(f64::from_bits(bits)))
460 }
461 FMT_UINT8 => Ok(MsgPackValue::UInt(self.read_u8()? as u64)),
462 FMT_UINT16 => Ok(MsgPackValue::UInt(self.read_u16_be()? as u64)),
463 FMT_UINT32 => Ok(MsgPackValue::UInt(self.read_u32_be()? as u64)),
464 FMT_UINT64 => Ok(MsgPackValue::UInt(self.read_u64_be()?)),
465 FMT_INT8 => Ok(MsgPackValue::Int(self.read_u8()? as i8 as i64)),
466 FMT_INT16 => {
467 let b = self.read_bytes(2)?;
468 Ok(MsgPackValue::Int(i16::from_be_bytes([b[0], b[1]]) as i64))
469 }
470 FMT_INT32 => {
471 let b = self.read_bytes(4)?;
472 Ok(MsgPackValue::Int(
473 i32::from_be_bytes([b[0], b[1], b[2], b[3]]) as i64,
474 ))
475 }
476 FMT_INT64 => {
477 let b = self.read_bytes(8)?;
478 Ok(MsgPackValue::Int(i64::from_be_bytes(
479 b.try_into()
480 .map_err(|_| IoError::FormatError("MsgPack: bad i64 bytes".into()))?,
481 )))
482 }
483 FMT_FIXEXT1 => self.read_ext_data(1),
484 FMT_FIXEXT2 => self.read_ext_data(2),
485 FMT_FIXEXT4 => self.read_ext_data(4),
486 FMT_FIXEXT8 => self.read_ext_data(8),
487 FMT_FIXEXT16 => self.read_ext_data(16),
488 FMT_STR8 => {
489 let n = self.read_u8()? as usize;
490 self.read_str_bytes(n)
491 }
492 FMT_STR16 => {
493 let n = self.read_u16_be()? as usize;
494 self.read_str_bytes(n)
495 }
496 FMT_STR32 => {
497 let n = self.read_u32_be()? as usize;
498 self.read_str_bytes(n)
499 }
500 FMT_ARRAY16 => {
501 let n = self.read_u16_be()? as usize;
502 self.read_array_items(n)
503 }
504 FMT_ARRAY32 => {
505 let n = self.read_u32_be()? as usize;
506 self.read_array_items(n)
507 }
508 FMT_MAP16 => {
509 let n = self.read_u16_be()? as usize;
510 self.read_map_items(n)
511 }
512 FMT_MAP32 => {
513 let n = self.read_u32_be()? as usize;
514 self.read_map_items(n)
515 }
516 other => Err(IoError::FormatError(format!(
517 "MsgPack: unknown format byte 0x{other:02x} at offset {}",
518 self.pos - 1
519 ))),
520 }
521 }
522}
523
524pub fn msgpack_encode(value: &MsgPackValue) -> Vec<u8> {
528 let mut w = MsgPackWriter::new();
529 w.write_value(value);
530 w.into_bytes()
531}
532
533pub fn msgpack_decode(data: &[u8]) -> Result<(MsgPackValue, usize)> {
535 let mut r = MsgPackReader::new(data);
536 let value = r.read_value()?;
537 Ok((value, r.position()))
538}
539
540pub fn roundtrip(value: &MsgPackValue) -> Result<MsgPackValue> {
544 let encoded = msgpack_encode(value);
545 let (decoded, _) = msgpack_decode(&encoded)?;
546 Ok(decoded)
547}
548
549pub struct MsgPackStreamReader<R: Read> {
553 inner: Cursor<Vec<u8>>,
554 _source: std::marker::PhantomData<R>,
555}
556
557impl<R: Read> MsgPackStreamReader<R> {
558 pub fn from_reader(mut source: R) -> Result<Self> {
560 let mut buf = Vec::new();
561 source.read_to_end(&mut buf).map_err(IoError::Io)?;
562 Ok(Self {
563 inner: Cursor::new(buf),
564 _source: std::marker::PhantomData,
565 })
566 }
567
568 pub fn read_next(&mut self) -> Result<MsgPackValue> {
570 let pos = self.inner.position() as usize;
571 let buf = self.inner.get_ref();
572 let remaining = &buf[pos..];
573 let mut reader = MsgPackReader::new(remaining);
574 let value = reader.read_value()?;
575 let consumed = reader.position();
576 self.inner.set_position((pos + consumed) as u64);
577 Ok(value)
578 }
579
580 pub fn is_done(&self) -> bool {
582 self.inner.position() >= self.inner.get_ref().len() as u64
583 }
584}
585
586#[cfg(test)]
589mod tests {
590 use super::*;
591
592 fn rt(v: MsgPackValue) -> MsgPackValue {
593 roundtrip(&v).expect("roundtrip failed")
594 }
595
596 #[test]
597 fn test_nil_roundtrip() {
598 assert_eq!(rt(MsgPackValue::Nil), MsgPackValue::Nil);
599 }
600
601 #[test]
602 fn test_bool_roundtrip() {
603 assert_eq!(rt(MsgPackValue::Bool(true)), MsgPackValue::Bool(true));
604 assert_eq!(rt(MsgPackValue::Bool(false)), MsgPackValue::Bool(false));
605 }
606
607 #[test]
608 fn test_positive_fixint() {
609 for i in 0i64..=127 {
610 assert_eq!(rt(MsgPackValue::Int(i)), MsgPackValue::Int(i));
611 }
612 }
613
614 #[test]
615 fn test_negative_fixint() {
616 for i in -32i64..=-1 {
617 assert_eq!(rt(MsgPackValue::Int(i)), MsgPackValue::Int(i));
618 }
619 }
620
621 #[test]
622 fn test_int_ranges() {
623 let vals: &[i64] = &[
624 i8::MIN as i64,
625 i8::MAX as i64,
626 i16::MIN as i64,
627 i16::MAX as i64,
628 i32::MIN as i64,
629 i32::MAX as i64,
630 i64::MIN,
631 i64::MAX,
632 ];
633 for &v in vals {
634 let enc = msgpack_encode(&MsgPackValue::Int(v));
635 let (dec, consumed) = msgpack_decode(&enc).expect("decode");
636 assert_eq!(consumed, enc.len());
637 match dec {
638 MsgPackValue::Int(d) => assert_eq!(d, v),
639 MsgPackValue::UInt(d) => assert_eq!(d as i64, v),
640 other => panic!("unexpected {other:?} for {v}"),
641 }
642 }
643 }
644
645 #[test]
646 fn test_uint_roundtrip() {
647 let vals: &[u64] = &[
648 0,
649 127,
650 128,
651 255,
652 256,
653 65535,
654 65536,
655 u32::MAX as u64,
656 u64::MAX,
657 ];
658 for &v in vals {
659 let enc = msgpack_encode(&MsgPackValue::UInt(v));
660 let (dec, _) = msgpack_decode(&enc).expect("decode");
661 match dec {
662 MsgPackValue::UInt(d) => assert_eq!(d, v),
663 MsgPackValue::Int(d) if d >= 0 => assert_eq!(d as u64, v),
664 other => panic!("unexpected {other:?} for {v}"),
665 }
666 }
667 }
668
669 #[test]
670 fn test_float32_roundtrip() {
671 let v = MsgPackValue::Float32(std::f32::consts::PI);
672 assert_eq!(rt(v), MsgPackValue::Float32(std::f32::consts::PI));
673 }
674
675 #[test]
676 fn test_float64_roundtrip() {
677 let v = MsgPackValue::Float64(std::f64::consts::PI);
678 assert_eq!(rt(v), MsgPackValue::Float64(std::f64::consts::PI));
679 }
680
681 #[test]
682 fn test_str_fixstr() {
683 let s = "hello".to_string();
684 assert_eq!(rt(MsgPackValue::Str(s.clone())), MsgPackValue::Str(s));
685 }
686
687 #[test]
688 fn test_str_str8() {
689 let s = "x".repeat(200);
690 assert_eq!(rt(MsgPackValue::Str(s.clone())), MsgPackValue::Str(s));
691 }
692
693 #[test]
694 fn test_str_str16() {
695 let s = "y".repeat(256);
696 assert_eq!(rt(MsgPackValue::Str(s.clone())), MsgPackValue::Str(s));
697 }
698
699 #[test]
700 fn test_bin_roundtrip() {
701 let b = vec![0u8, 1, 2, 3, 255];
702 assert_eq!(rt(MsgPackValue::Bin(b.clone())), MsgPackValue::Bin(b));
703 }
704
705 #[test]
706 fn test_array_roundtrip() {
707 let arr = MsgPackValue::Array(vec![
708 MsgPackValue::Int(1),
709 MsgPackValue::Str("hello".into()),
710 MsgPackValue::Nil,
711 ]);
712 assert_eq!(rt(arr.clone()), arr);
713 }
714
715 #[test]
716 fn test_map_roundtrip() {
717 let map = MsgPackValue::Map(vec![(
718 MsgPackValue::Str("key".into()),
719 MsgPackValue::Int(99),
720 )]);
721 assert_eq!(rt(map.clone()), map);
722 }
723
724 #[test]
725 fn test_ext_fixext1() {
726 let v = MsgPackValue::Ext(7, vec![0xab]);
727 assert_eq!(rt(v.clone()), v);
728 }
729
730 #[test]
731 fn test_ext_fixext8() {
732 let v = MsgPackValue::Ext(-1, vec![0u8; 8]);
733 assert_eq!(rt(v.clone()), v);
734 }
735
736 #[test]
737 fn test_writer_reader_integration() {
738 let mut w = MsgPackWriter::new();
739 w.write_map_header(2);
740 w.write_str("name");
741 w.write_str("Alice");
742 w.write_str("score");
743 w.write_int(100);
744 let bytes = w.into_bytes();
745
746 let mut r = MsgPackReader::new(&bytes);
747 let v = r.read_value().expect("decode");
748 assert!(r.is_empty());
749
750 match v {
751 MsgPackValue::Map(pairs) => {
752 assert_eq!(pairs.len(), 2);
753 assert_eq!(pairs[0].0, MsgPackValue::Str("name".into()));
754 assert_eq!(pairs[0].1, MsgPackValue::Str("Alice".into()));
755 assert_eq!(pairs[1].0, MsgPackValue::Str("score".into()));
756 assert_eq!(pairs[1].1, MsgPackValue::Int(100));
757 }
758 other => panic!("expected map, got {other:?}"),
759 }
760 }
761
762 #[test]
763 fn test_msgpack_decode_returns_consumed() {
764 let mut w = MsgPackWriter::new();
765 w.write_int(42);
766 w.write_nil();
767 let bytes = w.into_bytes();
768
769 let (val, consumed) = msgpack_decode(&bytes).expect("decode");
771 assert_eq!(val, MsgPackValue::Int(42));
772 assert_eq!(consumed, 1); }
774}