1use alloc::string::String;
11use alloc::vec::Vec;
12use core::fmt;
13
14#[derive(Debug, Clone)]
16pub enum Value {
17 Nil,
18 Bool(bool),
19 UInt(u64),
20 Int(i64),
21 Float(f64),
22 Bin(Vec<u8>),
23 Str(String),
24 Array(Vec<Value>),
25 Map(Vec<(Value, Value)>),
26}
27
28impl PartialEq for Value {
29 fn eq(&self, other: &Self) -> bool {
30 match (self, other) {
31 (Value::Nil, Value::Nil) => true,
32 (Value::Bool(a), Value::Bool(b)) => a == b,
33 (Value::UInt(a), Value::UInt(b)) => a == b,
34 (Value::Int(a), Value::Int(b)) => a == b,
35 (Value::Float(a), Value::Float(b)) => a.to_bits() == b.to_bits(),
36 (Value::Bin(a), Value::Bin(b)) => a == b,
37 (Value::Str(a), Value::Str(b)) => a == b,
38 (Value::Array(a), Value::Array(b)) => a == b,
39 (Value::Map(a), Value::Map(b)) => a == b,
40 _ => false,
41 }
42 }
43}
44
45impl Value {
46 pub fn as_uint(&self) -> Option<u64> {
48 match self {
49 Value::UInt(v) => Some(*v),
50 _ => None,
51 }
52 }
53
54 pub fn as_int(&self) -> Option<i64> {
56 match self {
57 Value::Int(v) => Some(*v),
58 _ => None,
59 }
60 }
61
62 pub fn as_integer(&self) -> Option<i64> {
64 match self {
65 Value::UInt(v) => {
66 if *v <= i64::MAX as u64 {
67 Some(*v as i64)
68 } else {
69 None
70 }
71 }
72 Value::Int(v) => Some(*v),
73 _ => None,
74 }
75 }
76
77 pub fn as_bool(&self) -> Option<bool> {
79 match self {
80 Value::Bool(v) => Some(*v),
81 _ => None,
82 }
83 }
84
85 pub fn as_float(&self) -> Option<f64> {
87 match self {
88 Value::Float(v) => Some(*v),
89 _ => None,
90 }
91 }
92
93 pub fn as_number(&self) -> Option<f64> {
95 match self {
96 Value::Float(v) => Some(*v),
97 Value::UInt(v) => Some(*v as f64),
98 Value::Int(v) => Some(*v as f64),
99 _ => None,
100 }
101 }
102
103 pub fn as_bin(&self) -> Option<&[u8]> {
105 match self {
106 Value::Bin(v) => Some(v),
107 _ => None,
108 }
109 }
110
111 pub fn as_str(&self) -> Option<&str> {
113 match self {
114 Value::Str(v) => Some(v),
115 _ => None,
116 }
117 }
118
119 pub fn as_array(&self) -> Option<&[Value]> {
121 match self {
122 Value::Array(v) => Some(v),
123 _ => None,
124 }
125 }
126
127 pub fn as_map(&self) -> Option<&[(Value, Value)]> {
129 match self {
130 Value::Map(v) => Some(v),
131 _ => None,
132 }
133 }
134
135 pub fn is_nil(&self) -> bool {
137 matches!(self, Value::Nil)
138 }
139
140 pub fn map_get(&self, key: &str) -> Option<&Value> {
142 self.as_map().and_then(|entries| {
143 entries.iter().find_map(|(k, v)| {
144 if let Value::Str(s) = k {
145 if s == key {
146 return Some(v);
147 }
148 }
149 None
150 })
151 })
152 }
153}
154
155const MAX_DEPTH: usize = 32;
157
158#[derive(Debug, Clone, PartialEq, Eq)]
160pub enum Error {
161 UnexpectedEof,
162 UnsupportedFormat(u8),
163 InvalidUtf8,
164 TrailingData,
165 MaxDepthExceeded,
166}
167
168impl fmt::Display for Error {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 match self {
171 Error::UnexpectedEof => write!(f, "Unexpected end of msgpack data"),
172 Error::UnsupportedFormat(b) => write!(f, "Unsupported msgpack format: 0x{:02x}", b),
173 Error::InvalidUtf8 => write!(f, "Invalid UTF-8 in msgpack string"),
174 Error::TrailingData => write!(f, "Trailing data after msgpack value"),
175 Error::MaxDepthExceeded => write!(f, "Maximum nesting depth exceeded"),
176 }
177 }
178}
179
180pub fn pack(value: &Value) -> Vec<u8> {
186 let mut buf = Vec::new();
187 pack_into(value, &mut buf);
188 buf
189}
190
191fn pack_into(value: &Value, buf: &mut Vec<u8>) {
192 match value {
193 Value::Nil => buf.push(0xc0),
194 Value::Bool(true) => buf.push(0xc3),
195 Value::Bool(false) => buf.push(0xc2),
196 Value::UInt(v) => pack_uint(*v, buf),
197 Value::Int(v) => pack_int(*v, buf),
198 Value::Float(v) => {
199 buf.push(0xcb);
200 buf.extend_from_slice(&v.to_bits().to_be_bytes());
201 }
202 Value::Bin(data) => pack_bin(data, buf),
203 Value::Str(s) => pack_str(s, buf),
204 Value::Array(items) => pack_array(items, buf),
205 Value::Map(entries) => pack_map(entries, buf),
206 }
207}
208
209pub(crate) fn pack_uint(v: u64, buf: &mut Vec<u8>) {
210 if v <= 127 {
211 buf.push(v as u8);
212 } else if v <= 0xFF {
213 buf.push(0xcc);
214 buf.push(v as u8);
215 } else if v <= 0xFFFF {
216 buf.push(0xcd);
217 buf.extend_from_slice(&(v as u16).to_be_bytes());
218 } else if v <= 0xFFFF_FFFF {
219 buf.push(0xce);
220 buf.extend_from_slice(&(v as u32).to_be_bytes());
221 } else {
222 buf.push(0xcf);
223 buf.extend_from_slice(&v.to_be_bytes());
224 }
225}
226
227fn pack_int(v: i64, buf: &mut Vec<u8>) {
228 if v >= 0 {
229 pack_uint(v as u64, buf);
230 } else if v >= -32 {
231 buf.push(v as u8); } else if v >= -128 {
233 buf.push(0xd0);
234 buf.push(v as i8 as u8);
235 } else if v >= -32768 {
236 buf.push(0xd1);
237 buf.extend_from_slice(&(v as i16).to_be_bytes());
238 } else if v >= -2_147_483_648 {
239 buf.push(0xd2);
240 buf.extend_from_slice(&(v as i32).to_be_bytes());
241 } else {
242 buf.push(0xd3);
243 buf.extend_from_slice(&v.to_be_bytes());
244 }
245}
246
247pub(crate) fn pack_bin(data: &[u8], buf: &mut Vec<u8>) {
248 let len = data.len();
249 if len <= 0xFF {
250 buf.push(0xc4);
251 buf.push(len as u8);
252 } else if len <= 0xFFFF {
253 buf.push(0xc5);
254 buf.extend_from_slice(&(len as u16).to_be_bytes());
255 } else {
256 buf.push(0xc6);
257 buf.extend_from_slice(&(len as u32).to_be_bytes());
258 }
259 buf.extend_from_slice(data);
260}
261
262pub(crate) fn pack_str(s: &str, buf: &mut Vec<u8>) {
263 let bytes = s.as_bytes();
264 let len = bytes.len();
265 if len <= 31 {
266 buf.push(0xa0 | len as u8);
267 } else if len <= 0xFF {
268 buf.push(0xd9);
269 buf.push(len as u8);
270 } else if len <= 0xFFFF {
271 buf.push(0xda);
272 buf.extend_from_slice(&(len as u16).to_be_bytes());
273 } else {
274 buf.push(0xdb);
275 buf.extend_from_slice(&(len as u32).to_be_bytes());
276 }
277 buf.extend_from_slice(bytes);
278}
279
280pub fn pack_array_header(len: usize, buf: &mut Vec<u8>) {
282 if len <= 15 {
283 buf.push(0x90 | len as u8);
284 } else if len <= 0xFFFF {
285 buf.push(0xdc);
286 buf.extend_from_slice(&(len as u16).to_be_bytes());
287 } else {
288 buf.push(0xdd);
289 buf.extend_from_slice(&(len as u32).to_be_bytes());
290 }
291}
292
293fn pack_map_header(len: usize, buf: &mut Vec<u8>) {
294 if len <= 15 {
295 buf.push(0x80 | len as u8);
296 } else if len <= 0xFFFF {
297 buf.push(0xde);
298 buf.extend_from_slice(&(len as u16).to_be_bytes());
299 } else {
300 buf.push(0xdf);
301 buf.extend_from_slice(&(len as u32).to_be_bytes());
302 }
303}
304
305pub fn pack_bin_into(data: &[u8], buf: &mut Vec<u8>) {
307 pack_bin(data, buf);
308}
309
310pub fn pack_ref_into(value: ValueRef<'_>, buf: &mut Vec<u8>) {
313 match value {
314 ValueRef::Nil => buf.push(0xc0),
315 ValueRef::Bool(true) => buf.push(0xc3),
316 ValueRef::Bool(false) => buf.push(0xc2),
317 ValueRef::UInt(v) => pack_uint(v, buf),
318 ValueRef::Int(v) => pack_int(v, buf),
319 ValueRef::Float(v) => {
320 buf.push(0xcb);
321 buf.extend_from_slice(&v.to_bits().to_be_bytes());
322 }
323 ValueRef::Bin(data) => pack_bin(data, buf),
324 ValueRef::Str(s) => pack_str(s, buf),
325 ValueRef::Array { len, .. } => {
326 pack_array_header(len, buf);
327 for item in value.array_items().into_iter().flatten() {
328 pack_ref_into(item, buf);
329 }
330 }
331 ValueRef::Map { len, .. } => {
332 pack_map_header(len, buf);
333 for (k, v) in value.map_entries().into_iter().flatten() {
334 pack_ref_into(k, buf);
335 pack_ref_into(v, buf);
336 }
337 }
338 }
339}
340
341fn pack_array(items: &[Value], buf: &mut Vec<u8>) {
342 pack_array_header(items.len(), buf);
343 for item in items {
344 pack_into(item, buf);
345 }
346}
347
348fn pack_map(entries: &[(Value, Value)], buf: &mut Vec<u8>) {
349 pack_map_header(entries.len(), buf);
350 for (k, v) in entries {
351 pack_into(k, buf);
352 pack_into(v, buf);
353 }
354}
355
356pub fn pack_str_map(entries: &[(&str, Value)]) -> Vec<u8> {
358 let map: Vec<(Value, Value)> = entries
359 .iter()
360 .map(|(k, v)| (Value::Str(String::from(*k)), v.clone()))
361 .collect();
362 pack(&Value::Map(map))
363}
364
365pub fn unpack(data: &[u8]) -> Result<(Value, usize), Error> {
372 unpack_depth(data, 0)
373}
374
375fn unpack_depth(data: &[u8], depth: usize) -> Result<(Value, usize), Error> {
376 let (value, consumed) = unpack_ref(data, depth)?;
377 Ok((value.to_owned_value()?, consumed))
378}
379
380pub fn unpack_exact(data: &[u8]) -> Result<Value, Error> {
382 let (value, consumed) = unpack(data)?;
383 if consumed != data.len() {
384 return Err(Error::TrailingData);
385 }
386 Ok(value)
387}
388
389pub fn unpack_exact_ref(data: &[u8]) -> Result<ValueRef<'_>, Error> {
392 let (value, consumed) = unpack_ref(data, 0)?;
393 if consumed != data.len() {
394 return Err(Error::TrailingData);
395 }
396 Ok(value)
397}
398
399fn ensure_len(data: &[u8], needed: usize) -> Result<(), Error> {
400 if data.len() < needed {
401 Err(Error::UnexpectedEof)
402 } else {
403 Ok(())
404 }
405}
406
407#[derive(Debug, Clone, Copy, PartialEq)]
412pub enum ValueRef<'a> {
413 Nil,
414 Bool(bool),
415 UInt(u64),
416 Int(i64),
417 Float(f64),
418 Bin(&'a [u8]),
419 Str(&'a str),
420 Array {
421 len: usize,
422 items: &'a [u8],
423 depth: usize,
424 },
425 Map {
426 len: usize,
427 entries: &'a [u8],
428 depth: usize,
429 },
430}
431
432impl<'a> ValueRef<'a> {
433 pub fn as_uint(&self) -> Option<u64> {
434 match self {
435 ValueRef::UInt(v) => Some(*v),
436 _ => None,
437 }
438 }
439
440 pub fn as_bin(&self) -> Option<&'a [u8]> {
441 match self {
442 ValueRef::Bin(v) => Some(v),
443 _ => None,
444 }
445 }
446
447 pub fn as_str(&self) -> Option<&'a str> {
448 match self {
449 ValueRef::Str(v) => Some(v),
450 _ => None,
451 }
452 }
453
454 pub fn is_nil(&self) -> bool {
455 matches!(self, ValueRef::Nil)
456 }
457
458 pub fn array_items(&self) -> Option<Items<'a>> {
460 match *self {
461 ValueRef::Array { len, items, depth } => Some(Items {
462 rest: items,
463 remaining: len,
464 depth: depth + 1,
465 }),
466 _ => None,
467 }
468 }
469
470 pub fn map_entries(&self) -> Option<Entries<'a>> {
472 match *self {
473 ValueRef::Map {
474 len,
475 entries,
476 depth,
477 } => Some(Entries(Items {
478 rest: entries,
479 remaining: len * 2,
480 depth: depth + 1,
481 })),
482 _ => None,
483 }
484 }
485
486 pub fn map_get(&self, key: &str) -> Option<ValueRef<'a>> {
489 self.map_entries()?
490 .find_map(|(k, v)| (k.as_str() == Some(key)).then_some(v))
491 }
492
493 fn to_owned_value(self) -> Result<Value, Error> {
494 Ok(match self {
495 ValueRef::Nil => Value::Nil,
496 ValueRef::Bool(b) => Value::Bool(b),
497 ValueRef::UInt(v) => Value::UInt(v),
498 ValueRef::Int(v) => Value::Int(v),
499 ValueRef::Float(v) => Value::Float(v),
500 ValueRef::Bin(b) => Value::Bin(b.to_vec()),
501 ValueRef::Str(s) => Value::Str(String::from(s)),
502 ValueRef::Array { len, .. } => {
503 let mut items = Vec::with_capacity(len);
504 for item in self.array_items().into_iter().flatten() {
505 items.push(item.to_owned_value()?);
506 }
507 Value::Array(items)
508 }
509 ValueRef::Map { len, .. } => {
510 let mut entries = Vec::with_capacity(len);
511 for (k, v) in self.map_entries().into_iter().flatten() {
512 entries.push((k.to_owned_value()?, v.to_owned_value()?));
513 }
514 Value::Map(entries)
515 }
516 })
517 }
518}
519
520#[derive(Debug, Clone)]
522pub struct Items<'a> {
523 rest: &'a [u8],
524 remaining: usize,
525 depth: usize,
526}
527
528impl<'a> Iterator for Items<'a> {
529 type Item = ValueRef<'a>;
530
531 fn next(&mut self) -> Option<ValueRef<'a>> {
532 if self.remaining == 0 {
533 return None;
534 }
535 self.remaining -= 1;
536 let (value, consumed) = unpack_ref(self.rest, self.depth).ok()?;
538 self.rest = &self.rest[consumed..];
539 Some(value)
540 }
541}
542
543#[derive(Debug, Clone)]
545pub struct Entries<'a>(Items<'a>);
546
547impl<'a> Iterator for Entries<'a> {
548 type Item = (ValueRef<'a>, ValueRef<'a>);
549
550 fn next(&mut self) -> Option<Self::Item> {
551 Some((self.0.next()?, self.0.next()?))
552 }
553}
554
555pub fn unpack_ref(data: &[u8], depth: usize) -> Result<(ValueRef<'_>, usize), Error> {
558 if data.is_empty() {
559 return Err(Error::UnexpectedEof);
560 }
561 if depth > MAX_DEPTH {
562 return Err(Error::MaxDepthExceeded);
563 }
564 let b = data[0];
565 match b {
566 0x00..=0x7f => Ok((ValueRef::UInt(b as u64), 1)),
568
569 0x80..=0x8f => unpack_map_ref(data, 1, (b & 0x0f) as usize, depth),
571
572 0x90..=0x9f => unpack_array_ref(data, 1, (b & 0x0f) as usize, depth),
574
575 0xa0..=0xbf => unpack_str_ref(data, 1, (b & 0x1f) as usize),
577
578 0xc0 => Ok((ValueRef::Nil, 1)),
580
581 0xc1 => Err(Error::UnsupportedFormat(b)),
583
584 0xc2 => Ok((ValueRef::Bool(false), 1)),
586 0xc3 => Ok((ValueRef::Bool(true), 1)),
587
588 0xca => {
590 ensure_len(data, 5)?;
591 let bits = u32::from_be_bytes([data[1], data[2], data[3], data[4]]);
592 Ok((ValueRef::Float(f32::from_bits(bits) as f64), 5))
593 }
594
595 0xcb => {
597 ensure_len(data, 9)?;
598 let bits = u64::from_be_bytes([
599 data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8],
600 ]);
601 Ok((ValueRef::Float(f64::from_bits(bits)), 9))
602 }
603
604 0xc4 => {
606 ensure_len(data, 2)?;
607 unpack_bin_ref(data, 2, data[1] as usize)
608 }
609 0xc5 => {
610 ensure_len(data, 3)?;
611 unpack_bin_ref(data, 3, u16::from_be_bytes([data[1], data[2]]) as usize)
612 }
613 0xc6 => {
614 ensure_len(data, 5)?;
615 let len = u32::from_be_bytes([data[1], data[2], data[3], data[4]]) as usize;
616 unpack_bin_ref(data, 5, len)
617 }
618
619 0xcc => {
621 ensure_len(data, 2)?;
622 Ok((ValueRef::UInt(data[1] as u64), 2))
623 }
624
625 0xcd => {
627 ensure_len(data, 3)?;
628 let v = u16::from_be_bytes([data[1], data[2]]);
629 Ok((ValueRef::UInt(v as u64), 3))
630 }
631
632 0xce => {
634 ensure_len(data, 5)?;
635 let v = u32::from_be_bytes([data[1], data[2], data[3], data[4]]);
636 Ok((ValueRef::UInt(v as u64), 5))
637 }
638
639 0xcf => {
641 ensure_len(data, 9)?;
642 let v = u64::from_be_bytes([
643 data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8],
644 ]);
645 Ok((ValueRef::UInt(v), 9))
646 }
647
648 0xd0 => {
650 ensure_len(data, 2)?;
651 Ok((ValueRef::Int(data[1] as i8 as i64), 2))
652 }
653
654 0xd1 => {
656 ensure_len(data, 3)?;
657 let v = i16::from_be_bytes([data[1], data[2]]);
658 Ok((ValueRef::Int(v as i64), 3))
659 }
660
661 0xd2 => {
663 ensure_len(data, 5)?;
664 let v = i32::from_be_bytes([data[1], data[2], data[3], data[4]]);
665 Ok((ValueRef::Int(v as i64), 5))
666 }
667
668 0xd3 => {
670 ensure_len(data, 9)?;
671 let v = i64::from_be_bytes([
672 data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8],
673 ]);
674 Ok((ValueRef::Int(v), 9))
675 }
676
677 0xd9 => {
679 ensure_len(data, 2)?;
680 unpack_str_ref(data, 2, data[1] as usize)
681 }
682 0xda => {
683 ensure_len(data, 3)?;
684 unpack_str_ref(data, 3, u16::from_be_bytes([data[1], data[2]]) as usize)
685 }
686 0xdb => {
687 ensure_len(data, 5)?;
688 let len = u32::from_be_bytes([data[1], data[2], data[3], data[4]]) as usize;
689 unpack_str_ref(data, 5, len)
690 }
691
692 0xdc => {
694 ensure_len(data, 3)?;
695 let len = u16::from_be_bytes([data[1], data[2]]) as usize;
696 unpack_array_ref(data, 3, len, depth)
697 }
698 0xdd => {
699 ensure_len(data, 5)?;
700 let len = u32::from_be_bytes([data[1], data[2], data[3], data[4]]) as usize;
701 unpack_array_ref(data, 5, len, depth)
702 }
703
704 0xde => {
706 ensure_len(data, 3)?;
707 let len = u16::from_be_bytes([data[1], data[2]]) as usize;
708 unpack_map_ref(data, 3, len, depth)
709 }
710 0xdf => {
711 ensure_len(data, 5)?;
712 let len = u32::from_be_bytes([data[1], data[2], data[3], data[4]]) as usize;
713 unpack_map_ref(data, 5, len, depth)
714 }
715
716 0xe0..=0xff => Ok((ValueRef::Int(b as i8 as i64), 1)),
718
719 _ => Err(Error::UnsupportedFormat(b)),
720 }
721}
722
723fn unpack_bin_ref(data: &[u8], offset: usize, len: usize) -> Result<(ValueRef<'_>, usize), Error> {
724 let end = offset.checked_add(len).ok_or(Error::UnexpectedEof)?;
725 ensure_len(data, end)?;
726 Ok((ValueRef::Bin(&data[offset..end]), end))
727}
728
729fn unpack_str_ref(data: &[u8], offset: usize, len: usize) -> Result<(ValueRef<'_>, usize), Error> {
730 let end = offset.checked_add(len).ok_or(Error::UnexpectedEof)?;
731 ensure_len(data, end)?;
732 let s = core::str::from_utf8(&data[offset..end]).map_err(|_| Error::InvalidUtf8)?;
733 Ok((ValueRef::Str(s), end))
734}
735
736fn skip_items(data: &[u8], start: usize, count: usize, depth: usize) -> Result<usize, Error> {
739 let mut offset = start;
740 for _ in 0..count {
741 let (_, consumed) = unpack_ref(&data[offset..], depth + 1)?;
742 offset += consumed;
743 }
744 Ok(offset)
745}
746
747fn unpack_array_ref(
748 data: &[u8],
749 start: usize,
750 count: usize,
751 depth: usize,
752) -> Result<(ValueRef<'_>, usize), Error> {
753 if count > data.len().saturating_sub(start) {
754 return Err(Error::UnexpectedEof);
755 }
756 let end = skip_items(data, start, count, depth)?;
757 Ok((
758 ValueRef::Array {
759 len: count,
760 items: &data[start..end],
761 depth,
762 },
763 end,
764 ))
765}
766
767fn unpack_map_ref(
768 data: &[u8],
769 start: usize,
770 count: usize,
771 depth: usize,
772) -> Result<(ValueRef<'_>, usize), Error> {
773 let items = count
774 .checked_mul(2)
775 .filter(|items| *items <= data.len().saturating_sub(start))
776 .ok_or(Error::UnexpectedEof)?;
777 let end = skip_items(data, start, items, depth)?;
778 Ok((
779 ValueRef::Map {
780 len: count,
781 entries: &data[start..end],
782 depth,
783 },
784 end,
785 ))
786}
787
788#[cfg(test)]
789mod tests {
790 use super::*;
791
792 fn encoded_corpus() -> Vec<Vec<u8>> {
795 let mut corpus: Vec<Vec<u8>> = vec![
796 vec![0xc0],
797 vec![0xc2],
798 vec![0xc3],
799 vec![0x7f],
800 vec![0xe0],
801 vec![0xcc, 0x05],
802 vec![0xcd, 0x00, 0x05],
803 vec![0xcf, 0, 0, 0, 0, 0, 0, 0, 1],
804 vec![0xd0, 0x05],
805 vec![0xd3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00],
806 vec![0xca, 0x3f, 0x80, 0x00, 0x00],
807 vec![0xcb, 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18],
808 vec![0xc4, 0x02, 0xaa, 0xbb],
809 vec![0xc5, 0x00, 0x01, 0xaa],
810 vec![0xa3, b'a', b'b', b'c'],
811 vec![0xd9, 0x01, b'x'],
812 vec![0x93, 0x01, 0xc4, 0x01, 0xff, 0x92, 0xc0, 0xa1, b'k'],
813 vec![0xdc, 0x00, 0x02, 0xc3, 0xc2],
814 vec![
815 0x82, 0xa1, b'a', 0x01, 0xa1, b'a', 0x92, 0x02, 0xca, 0, 0, 0, 0,
816 ],
817 vec![0xde, 0x00, 0x01, 0x01, 0x80],
818 ];
819 corpus.push(pack(&Value::Array(vec![
820 Value::Float(1.5),
821 Value::Bin(vec![7; 300]),
822 Value::Str("s".repeat(40)),
823 Value::Array((0..20).map(Value::UInt).collect()),
824 Value::Map((0..20).map(|i| (Value::Int(-i), Value::Nil)).collect()),
825 ])));
826 corpus
827 }
828
829 #[test]
830 fn packing_a_borrowed_value_matches_packing_its_owned_form() {
831 let mut inputs = encoded_corpus();
832 let mut extra = Vec::new();
835 for input in &inputs {
836 for end in 0..input.len() {
837 extra.push(input[..end].to_vec());
838 }
839 for i in 0..input.len() {
840 for byte in [0x00, 0x7f, 0x90, 0xc4, 0xca, 0xdc, 0xff] {
841 let mut corrupt = input.clone();
842 corrupt[i] = byte;
843 extra.push(corrupt);
844 }
845 }
846 }
847 inputs.extend(extra);
848 let mut accepted = 0;
849 for input in &inputs {
850 let owned = unpack_exact(input);
851 let borrowed = unpack_exact_ref(input);
852 assert_eq!(owned.is_ok(), borrowed.is_ok(), "{input:02x?}");
853 if let (Ok(owned), Ok(borrowed)) = (owned, borrowed) {
854 let mut packed = Vec::new();
855 pack_ref_into(borrowed, &mut packed);
856 assert_eq!(packed, pack(&owned), "{input:02x?}");
857 accepted += 1;
858 }
859 }
860 assert!(accepted > 100);
861 }
862
863 fn roundtrip(v: &Value) -> Value {
864 let packed = pack(v);
865 let (unpacked, consumed) = unpack(&packed).unwrap();
866 assert_eq!(consumed, packed.len(), "all bytes consumed");
867 unpacked
868 }
869
870 #[test]
871 fn test_nil() {
872 let packed = pack(&Value::Nil);
873 assert_eq!(packed, vec![0xc0]);
874 assert_eq!(roundtrip(&Value::Nil), Value::Nil);
875 }
876
877 #[test]
878 fn test_bool() {
879 assert_eq!(pack(&Value::Bool(true)), vec![0xc3]);
880 assert_eq!(pack(&Value::Bool(false)), vec![0xc2]);
881 assert_eq!(roundtrip(&Value::Bool(true)), Value::Bool(true));
882 assert_eq!(roundtrip(&Value::Bool(false)), Value::Bool(false));
883 }
884
885 #[test]
886 fn test_positive_fixint() {
887 assert_eq!(pack(&Value::UInt(0)), vec![0x00]);
888 assert_eq!(pack(&Value::UInt(127)), vec![0x7f]);
889 assert_eq!(roundtrip(&Value::UInt(0)), Value::UInt(0));
890 assert_eq!(roundtrip(&Value::UInt(42)), Value::UInt(42));
891 assert_eq!(roundtrip(&Value::UInt(127)), Value::UInt(127));
892 }
893
894 #[test]
895 fn test_uint8() {
896 assert_eq!(pack(&Value::UInt(128)), vec![0xcc, 0x80]);
897 assert_eq!(pack(&Value::UInt(255)), vec![0xcc, 0xff]);
898 assert_eq!(roundtrip(&Value::UInt(128)), Value::UInt(128));
899 assert_eq!(roundtrip(&Value::UInt(255)), Value::UInt(255));
900 }
901
902 #[test]
903 fn test_uint16() {
904 assert_eq!(pack(&Value::UInt(256)), vec![0xcd, 0x01, 0x00]);
905 assert_eq!(roundtrip(&Value::UInt(256)), Value::UInt(256));
906 assert_eq!(roundtrip(&Value::UInt(0xFFFF)), Value::UInt(0xFFFF));
907 }
908
909 #[test]
910 fn test_uint32() {
911 assert_eq!(
912 pack(&Value::UInt(0x10000)),
913 vec![0xce, 0x00, 0x01, 0x00, 0x00]
914 );
915 assert_eq!(roundtrip(&Value::UInt(0x10000)), Value::UInt(0x10000));
916 assert_eq!(roundtrip(&Value::UInt(0xFFFFFFFF)), Value::UInt(0xFFFFFFFF));
917 }
918
919 #[test]
920 fn test_uint64() {
921 let big = 0x1_0000_0000u64;
922 assert_eq!(roundtrip(&Value::UInt(big)), Value::UInt(big));
923 let huge = u64::MAX;
924 assert_eq!(roundtrip(&Value::UInt(huge)), Value::UInt(huge));
925 }
926
927 #[test]
928 fn test_negative_fixint() {
929 assert_eq!(pack(&Value::Int(-1)), vec![0xff]);
931 assert_eq!(pack(&Value::Int(-32)), vec![0xe0]);
932 assert_eq!(roundtrip(&Value::Int(-1)), Value::Int(-1));
933 assert_eq!(roundtrip(&Value::Int(-32)), Value::Int(-32));
934 }
935
936 #[test]
937 fn test_int8() {
938 assert_eq!(pack(&Value::Int(-33)), vec![0xd0, 0xdf]);
939 assert_eq!(roundtrip(&Value::Int(-33)), Value::Int(-33));
940 assert_eq!(roundtrip(&Value::Int(-128)), Value::Int(-128));
941 }
942
943 #[test]
944 fn test_int16() {
945 assert_eq!(roundtrip(&Value::Int(-129)), Value::Int(-129));
946 assert_eq!(roundtrip(&Value::Int(-32768)), Value::Int(-32768));
947 }
948
949 #[test]
950 fn test_int32() {
951 assert_eq!(roundtrip(&Value::Int(-32769)), Value::Int(-32769));
952 }
953
954 #[test]
955 fn test_positive_int_packed_as_uint() {
956 let packed = pack(&Value::Int(42));
958 assert_eq!(packed, vec![42]); }
960
961 #[test]
962 fn test_fixstr() {
963 let v = Value::Str(String::from("t"));
964 let packed = pack(&v);
965 assert_eq!(packed[0], 0xa1); assert_eq!(roundtrip(&v), v);
967
968 let v = Value::Str(String::from("hello"));
969 assert_eq!(roundtrip(&v), v);
970
971 let v = Value::Str(String::new());
973 assert_eq!(pack(&v), vec![0xa0]);
974 assert_eq!(roundtrip(&v), v);
975 }
976
977 #[test]
978 fn test_str8() {
979 let s: String = "a".repeat(32);
980 let v = Value::Str(s);
981 let packed = pack(&v);
982 assert_eq!(packed[0], 0xd9);
983 assert_eq!(packed[1], 32);
984 assert_eq!(roundtrip(&v), v);
985 }
986
987 #[test]
988 fn test_bin8() {
989 let v = Value::Bin(vec![1, 2, 3]);
990 let packed = pack(&v);
991 assert_eq!(packed[0], 0xc4);
992 assert_eq!(packed[1], 3);
993 assert_eq!(roundtrip(&v), v);
994 }
995
996 #[test]
997 fn test_bin16() {
998 let data = vec![0xAB; 300];
999 let v = Value::Bin(data);
1000 let packed = pack(&v);
1001 assert_eq!(packed[0], 0xc5);
1002 assert_eq!(roundtrip(&v), v);
1003 }
1004
1005 #[test]
1006 fn test_bin32() {
1007 let data = vec![0xCD; 70000];
1010 let v = Value::Bin(data);
1011 let packed = pack(&v);
1012 assert_eq!(packed[0], 0xc6);
1013 assert_eq!(roundtrip(&v), v);
1014 }
1015
1016 #[test]
1017 fn test_fixarray() {
1018 let v = Value::Array(vec![Value::UInt(1), Value::UInt(2), Value::UInt(3)]);
1019 let packed = pack(&v);
1020 assert_eq!(packed[0], 0x93); assert_eq!(roundtrip(&v), v);
1022
1023 let v = Value::Array(vec![]);
1025 assert_eq!(pack(&v), vec![0x90]);
1026 assert_eq!(roundtrip(&v), v);
1027 }
1028
1029 #[test]
1030 fn test_fixmap() {
1031 let v = Value::Map(vec![
1032 (Value::Str(String::from("a")), Value::UInt(1)),
1033 (Value::Str(String::from("b")), Value::UInt(2)),
1034 ]);
1035 let packed = pack(&v);
1036 assert_eq!(packed[0], 0x82); assert_eq!(roundtrip(&v), v);
1038 }
1039
1040 #[test]
1041 fn test_nested_structure() {
1042 let v = Value::Map(vec![
1043 (Value::Str(String::from("t")), Value::UInt(1000)),
1044 (Value::Str(String::from("m")), Value::Bin(vec![0xAA; 10])),
1045 (Value::Str(String::from("q")), Value::Nil),
1046 ]);
1047 assert_eq!(roundtrip(&v), v);
1048 }
1049
1050 #[test]
1051 fn test_pack_str_map() {
1052 let packed = pack_str_map(&[("x", Value::UInt(42)), ("y", Value::Bool(true))]);
1053 let (v, _) = unpack(&packed).unwrap();
1054 assert_eq!(v.map_get("x").unwrap().as_uint(), Some(42));
1055 assert_eq!(v.map_get("y").unwrap().as_bool(), Some(true));
1056 }
1057
1058 #[test]
1059 fn test_map_get_missing_key() {
1060 let v = Value::Map(vec![(Value::Str(String::from("a")), Value::UInt(1))]);
1061 assert!(v.map_get("b").is_none());
1062 }
1063
1064 #[test]
1065 fn test_hmu_array_format() {
1066 let v = Value::Array(vec![
1068 Value::UInt(2),
1069 Value::Bin(vec![0x11, 0x22, 0x33, 0x44, 0xAA, 0xBB, 0xCC, 0xDD]),
1070 ]);
1071 assert_eq!(roundtrip(&v), v);
1072 }
1073
1074 #[test]
1075 fn test_decode_error_eof() {
1076 assert_eq!(unpack(&[]), Err(Error::UnexpectedEof));
1077 assert_eq!(unpack(&[0xc4, 0x05]), Err(Error::UnexpectedEof));
1079 }
1080
1081 #[test]
1082 fn test_declared_array_length_cannot_force_large_allocation() {
1083 let data = [0xdd, 0xff, 0xff, 0xff, 0xff];
1084 assert_eq!(unpack(&data), Err(Error::UnexpectedEof));
1085 }
1086
1087 #[test]
1088 fn test_declared_map_length_cannot_force_large_allocation() {
1089 let data = [0xdf, 0x7f, 0xff, 0xff, 0xff];
1090 assert_eq!(unpack(&data), Err(Error::UnexpectedEof));
1091 }
1092
1093 #[test]
1094 fn test_unpack_exact_trailing() {
1095 let packed = pack(&Value::UInt(42));
1096 let mut with_extra = packed.clone();
1097 with_extra.push(0x00);
1098 assert!(unpack_exact(&with_extra).is_err());
1099 assert!(unpack_exact(&packed).is_ok());
1100 }
1101
1102 #[test]
1103 fn test_value_accessors() {
1104 assert_eq!(Value::UInt(42).as_uint(), Some(42));
1105 assert_eq!(Value::UInt(42).as_int(), None);
1106 assert_eq!(Value::UInt(42).as_integer(), Some(42));
1107 assert_eq!(Value::Int(-5).as_integer(), Some(-5));
1108 assert_eq!(Value::Bool(true).as_bool(), Some(true));
1109 assert_eq!(Value::Bin(vec![1]).as_bin(), Some(&[1u8][..]));
1110 assert_eq!(Value::Str(String::from("x")).as_str(), Some("x"));
1111 assert!(Value::Nil.is_nil());
1112 }
1113
1114 #[test]
1115 fn test_max_depth_exceeded() {
1116 let mut data = Vec::new();
1118 data.extend(core::iter::repeat_n(0x91, MAX_DEPTH + 2)); data.push(0x01); assert_eq!(unpack(&data), Err(Error::MaxDepthExceeded));
1121 }
1122
1123 #[test]
1124 fn test_depth_within_limit() {
1125 let mut data = Vec::new();
1127 data.extend(core::iter::repeat_n(0x91, 5)); data.push(0x01); let (val, _) = unpack(&data).unwrap();
1130 let mut current = &val;
1132 for _ in 0..5 {
1133 current = ¤t.as_array().unwrap()[0];
1134 }
1135 assert_eq!(current.as_uint(), Some(1));
1136 }
1137
1138 #[test]
1139 fn test_int64_roundtrip() {
1140 let v = Value::Int(i64::MIN);
1141 assert_eq!(roundtrip(&v), v);
1142 let v = Value::Int(-2_147_483_649); assert_eq!(roundtrip(&v), v);
1144 }
1145
1146 #[test]
1147 fn test_str16_roundtrip() {
1148 let s: String = "x".repeat(256);
1149 let v = Value::Str(s);
1150 let packed = pack(&v);
1151 assert_eq!(packed[0], 0xda); assert_eq!(roundtrip(&v), v);
1153 }
1154
1155 #[test]
1156 fn test_array16_roundtrip() {
1157 let items: Vec<Value> = (0..16).map(Value::UInt).collect();
1158 let v = Value::Array(items);
1159 let packed = pack(&v);
1160 assert_eq!(packed[0], 0xdc); assert_eq!(roundtrip(&v), v);
1162 }
1163
1164 #[test]
1165 fn test_map16_roundtrip() {
1166 let entries: Vec<(Value, Value)> = (0..16)
1167 .map(|i| (Value::UInt(i), Value::Bool(i % 2 == 0)))
1168 .collect();
1169 let v = Value::Map(entries);
1170 let packed = pack(&v);
1171 assert_eq!(packed[0], 0xde); assert_eq!(roundtrip(&v), v);
1173 }
1174
1175 #[test]
1176 fn test_unsupported_format() {
1177 assert_eq!(unpack(&[0xc1]), Err(Error::UnsupportedFormat(0xc1)));
1179 }
1180}