1use crate::{
3 error::{InvalidCidPrefix, LengthOutOfRange, UnexpectedCode, UnexpectedEof, UnknownTag},
4 RawCborCodec,
5};
6use byteorder::{BigEndian, ByteOrder};
7use core::convert::TryFrom;
8use libipld_core::{
9 cid::Cid,
10 codec::{Decode, References},
11 error::Result,
12 ipld::Ipld,
13 raw_value::SkipOne,
14};
15use std::{
16 collections::BTreeMap,
17 io::{Read, Seek, SeekFrom},
18 sync::Arc,
19};
20
21pub fn read_u8<R: Read + Seek>(r: &mut R) -> Result<u8> {
23 let mut buf = [0; 1];
24 r.read_exact(&mut buf)?;
25 Ok(buf[0])
26}
27
28pub fn read_u16<R: Read + Seek>(r: &mut R) -> Result<u16> {
30 let mut buf = [0; 2];
31 r.read_exact(&mut buf)?;
32 Ok(BigEndian::read_u16(&buf))
33}
34
35pub fn read_u32<R: Read + Seek>(r: &mut R) -> Result<u32> {
37 let mut buf = [0; 4];
38 r.read_exact(&mut buf)?;
39 Ok(BigEndian::read_u32(&buf))
40}
41
42pub fn read_u64<R: Read + Seek>(r: &mut R) -> Result<u64> {
44 let mut buf = [0; 8];
45 r.read_exact(&mut buf)?;
46 Ok(BigEndian::read_u64(&buf))
47}
48
49pub fn read_f32<R: Read + Seek>(r: &mut R) -> Result<f32> {
51 let mut buf = [0; 4];
52 r.read_exact(&mut buf)?;
53 Ok(BigEndian::read_f32(&buf))
54}
55
56pub fn read_f64<R: Read + Seek>(r: &mut R) -> Result<f64> {
58 let mut buf = [0; 8];
59 r.read_exact(&mut buf)?;
60 Ok(BigEndian::read_f64(&buf))
61}
62
63pub fn read_bytes<R: Read + Seek>(r: &mut R, len: usize) -> Result<Vec<u8>> {
65 let mut buf = Vec::with_capacity(len.min(16 * 1024));
67 r.take(len as u64).read_to_end(&mut buf)?;
68 if buf.len() != len {
69 return Err(UnexpectedEof.into());
70 }
71 Ok(buf)
72}
73
74pub fn read_str<R: Read + Seek>(r: &mut R, len: usize) -> Result<String> {
76 let bytes = read_bytes(r, len)?;
77 Ok(String::from_utf8(bytes)?)
78}
79
80pub fn read_list<R: Read + Seek, T: Decode<RawCborCodec>>(r: &mut R, len: usize) -> Result<Vec<T>> {
82 let max_alloc = (16 * 1024) / std::mem::size_of::<T>();
86
87 let mut list: Vec<T> = Vec::with_capacity(len.min(max_alloc));
88 for _ in 0..len {
89 list.push(T::decode(RawCborCodec, r)?);
90 }
91 Ok(list)
92}
93
94pub fn read_list_il<R: Read + Seek, T: Decode<RawCborCodec>>(r: &mut R) -> Result<Vec<T>> {
96 let mut list: Vec<T> = Vec::new();
97 loop {
98 let major = read_u8(r)?;
99 if major == 0xff {
100 break;
101 }
102 r.seek(SeekFrom::Current(-1))?;
103 let value = T::decode(RawCborCodec, r)?;
104 list.push(value);
105 }
106 Ok(list)
107}
108
109pub fn read_map<R: Read + Seek, K: Decode<RawCborCodec> + Ord, T: Decode<RawCborCodec>>(
111 r: &mut R,
112 len: usize,
113) -> Result<BTreeMap<K, T>> {
114 let mut map: BTreeMap<K, T> = BTreeMap::new();
115 for _ in 0..len {
116 let key = K::decode(RawCborCodec, r)?;
117 let value = T::decode(RawCborCodec, r)?;
118 map.insert(key, value);
119 }
120 Ok(map)
121}
122
123pub fn read_map_il<R: Read + Seek, K: Decode<RawCborCodec> + Ord, T: Decode<RawCborCodec>>(
125 r: &mut R,
126) -> Result<BTreeMap<K, T>> {
127 let mut map: BTreeMap<K, T> = BTreeMap::new();
128 loop {
129 let major = read_u8(r)?;
130 if major == 0xff {
131 break;
132 }
133 r.seek(SeekFrom::Current(-1))?;
134 let key = K::decode(RawCborCodec, r)?;
135 let value = T::decode(RawCborCodec, r)?;
136 map.insert(key, value);
137 }
138 Ok(map)
139}
140
141pub fn read_link<R: Read + Seek>(r: &mut R) -> Result<Cid> {
143 let ty = read_u8(r)?;
144 if ty != 0x58 {
145 return Err(UnknownTag(ty).into());
146 }
147 let len = read_u8(r)?;
148 if len == 0 {
149 return Err(LengthOutOfRange::new::<Cid>().into());
150 }
151 let bytes = read_bytes(r, len as usize)?;
152 if bytes[0] != 0 {
153 return Err(InvalidCidPrefix(bytes[0]).into());
154 }
155
156 Ok(Cid::try_from(&bytes[1..])?)
159}
160
161pub fn read_len<R: Read + Seek>(r: &mut R, major: u8) -> Result<usize> {
163 Ok(match major {
164 0x00..=0x17 => major as usize,
165 0x18 => read_u8(r)? as usize,
166 0x19 => read_u16(r)? as usize,
167 0x1a => read_u32(r)? as usize,
168 0x1b => {
169 let len = read_u64(r)?;
170 if len > usize::max_value() as u64 {
171 return Err(LengthOutOfRange::new::<usize>().into());
172 }
173 len as usize
174 }
175 major => return Err(UnexpectedCode::new::<usize>(major).into()),
176 })
177}
178
179impl Decode<RawCborCodec> for bool {
180 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
181 let major = read_u8(r)?;
182 let result = match major {
183 0xf4 => false,
184 0xf5 => true,
185 _ => {
186 return Err(UnexpectedCode::new::<Self>(major).into());
187 }
188 };
189 Ok(result)
190 }
191}
192
193impl Decode<RawCborCodec> for u8 {
194 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
195 let major = read_u8(r)?;
196 let result = match major {
197 0x00..=0x17 => major,
198 0x18 => read_u8(r)?,
199 _ => {
200 return Err(UnexpectedCode::new::<Self>(major).into());
201 }
202 };
203 Ok(result)
204 }
205}
206
207impl Decode<RawCborCodec> for u16 {
208 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
209 let major = read_u8(r)?;
210 let result = match major {
211 0x00..=0x17 => major as u16,
212 0x18 => read_u8(r)? as u16,
213 0x19 => read_u16(r)?,
214 _ => {
215 return Err(UnexpectedCode::new::<Self>(major).into());
216 }
217 };
218 Ok(result)
219 }
220}
221
222impl Decode<RawCborCodec> for u32 {
223 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
224 let major = read_u8(r)?;
225 let result = match major {
226 0x00..=0x17 => major as u32,
227 0x18 => read_u8(r)? as u32,
228 0x19 => read_u16(r)? as u32,
229 0x1a => read_u32(r)?,
230 _ => {
231 return Err(UnexpectedCode::new::<Self>(major).into());
232 }
233 };
234 Ok(result)
235 }
236}
237
238impl Decode<RawCborCodec> for u64 {
239 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
240 let major = read_u8(r)?;
241 let result = match major {
242 0x00..=0x17 => major as u64,
243 0x18 => read_u8(r)? as u64,
244 0x19 => read_u16(r)? as u64,
245 0x1a => read_u32(r)? as u64,
246 0x1b => read_u64(r)?,
247 _ => {
248 return Err(UnexpectedCode::new::<Self>(major).into());
249 }
250 };
251 Ok(result)
252 }
253}
254
255impl Decode<RawCborCodec> for i8 {
256 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
257 let major = read_u8(r)?;
258 let result = match major {
259 0x20..=0x37 => -1 - (major - 0x20) as i8,
260 0x38 => -1 - read_u8(r)? as i8,
261 _ => {
262 return Err(UnexpectedCode::new::<Self>(major).into());
263 }
264 };
265 Ok(result)
266 }
267}
268
269impl Decode<RawCborCodec> for i16 {
270 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
271 let major = read_u8(r)?;
272 let result = match major {
273 0x20..=0x37 => -1 - (major - 0x20) as i16,
274 0x38 => -1 - read_u8(r)? as i16,
275 0x39 => -1 - read_u16(r)? as i16,
276 _ => {
277 return Err(UnexpectedCode::new::<Self>(major).into());
278 }
279 };
280 Ok(result)
281 }
282}
283
284impl Decode<RawCborCodec> for i32 {
285 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
286 let major = read_u8(r)?;
287 let result = match major {
288 0x20..=0x37 => -1 - (major - 0x20) as i32,
289 0x38 => -1 - read_u8(r)? as i32,
290 0x39 => -1 - read_u16(r)? as i32,
291 0x3a => -1 - read_u32(r)? as i32,
292 _ => {
293 return Err(UnexpectedCode::new::<Self>(major).into());
294 }
295 };
296 Ok(result)
297 }
298}
299
300impl Decode<RawCborCodec> for i64 {
301 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
302 let major = read_u8(r)?;
303 let result = match major {
304 0x20..=0x37 => -1 - (major - 0x20) as i64,
305 0x38 => -1 - read_u8(r)? as i64,
306 0x39 => -1 - read_u16(r)? as i64,
307 0x3a => -1 - read_u32(r)? as i64,
308 0x3b => -1 - read_u64(r)? as i64,
309 _ => {
310 return Err(UnexpectedCode::new::<Self>(major).into());
311 }
312 };
313 Ok(result)
314 }
315}
316
317impl Decode<RawCborCodec> for f32 {
318 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
319 let major = read_u8(r)?;
320 let result = match major {
321 0xfa => read_f32(r)?,
322 _ => {
323 return Err(UnexpectedCode::new::<Self>(major).into());
324 }
325 };
326 Ok(result)
327 }
328}
329
330impl Decode<RawCborCodec> for f64 {
331 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
332 let major = read_u8(r)?;
333 let result = match major {
334 0xfa => read_f32(r)? as f64,
335 0xfb => read_f64(r)?,
336 _ => {
337 return Err(UnexpectedCode::new::<Self>(major).into());
338 }
339 };
340 Ok(result)
341 }
342}
343
344impl Decode<RawCborCodec> for String {
345 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
346 let major = read_u8(r)?;
347 let result = match major {
348 0x60..=0x7b => {
349 let len = read_len(r, major - 0x60)?;
350 read_str(r, len)?
351 }
352 _ => {
353 return Err(UnexpectedCode::new::<Self>(major).into());
354 }
355 };
356 Ok(result)
357 }
358}
359
360impl Decode<RawCborCodec> for Cid {
361 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
362 let major = read_u8(r)?;
363 if major == 0xd8 {
364 if let Ok(tag) = read_u8(r) {
365 if tag == 42 {
366 return read_link(r);
367 }
368 }
369 }
370 Err(UnexpectedCode::new::<Self>(major).into())
371 }
372}
373
374impl Decode<RawCborCodec> for Box<[u8]> {
375 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
376 let major = read_u8(r)?;
377 let result = match major {
378 0x40..=0x5b => {
379 let len = read_len(r, major - 0x40)?;
380 read_bytes(r, len)?.into_boxed_slice()
381 }
382 _ => {
383 return Err(UnexpectedCode::new::<Self>(major).into());
384 }
385 };
386 Ok(result)
387 }
388}
389
390impl<T: Decode<RawCborCodec>> Decode<RawCborCodec> for Option<T> {
391 fn decode<R: Read + Seek>(c: RawCborCodec, r: &mut R) -> Result<Self> {
392 let major = read_u8(r)?;
393 let result = match major {
394 0xf6 => None,
395 0xf7 => None,
396 _ => {
397 r.seek(SeekFrom::Current(-1))?;
398 Some(T::decode(c, r)?)
399 }
400 };
401 Ok(result)
402 }
403}
404
405impl<T: Decode<RawCborCodec>> Decode<RawCborCodec> for Vec<T> {
406 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
407 let major = read_u8(r)?;
408 let result = match major {
409 0x80..=0x9b => {
410 let len = read_len(r, major - 0x80)?;
411 read_list(r, len)?
412 }
413 0x9f => read_list_il(r)?,
414 _ => {
415 return Err(UnexpectedCode::new::<Self>(major).into());
416 }
417 };
418 Ok(result)
419 }
420}
421
422impl<K: Decode<RawCborCodec> + Ord, T: Decode<RawCborCodec>> Decode<RawCborCodec> for BTreeMap<K, T> {
423 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
424 let major = read_u8(r)?;
425 let result = match major {
426 0xa0..=0xbb => {
427 let len = read_len(r, major - 0xa0)?;
428 read_map(r, len)?
429 }
430 0xbf => read_map_il(r)?,
431 _ => {
432 return Err(UnexpectedCode::new::<Self>(major).into());
433 }
434 };
435 Ok(result)
436 }
437}
438
439impl Decode<RawCborCodec> for Ipld {
441 fn decode<R: Read + Seek>(_: RawCborCodec, r: &mut R) -> Result<Self> {
442 let major = read_u8(r)?;
443 let ipld = match major {
444 0x00..=0x17 => Self::Integer(major as i128),
446 0x18 => Self::Integer(read_u8(r)? as i128),
447 0x19 => Self::Integer(read_u16(r)? as i128),
448 0x1a => Self::Integer(read_u32(r)? as i128),
449 0x1b => Self::Integer(read_u64(r)? as i128),
450
451 0x20..=0x37 => Self::Integer(-1 - (major - 0x20) as i128),
453 0x38 => Self::Integer(-1 - read_u8(r)? as i128),
454 0x39 => Self::Integer(-1 - read_u16(r)? as i128),
455 0x3a => Self::Integer(-1 - read_u32(r)? as i128),
456 0x3b => Self::Integer(-1 - read_u64(r)? as i128),
457
458 0x40..=0x5b => {
460 let len = read_len(r, major - 0x40)?;
461 let bytes = read_bytes(r, len as usize)?;
462 Self::Bytes(bytes)
463 }
464
465 0x60..=0x7b => {
467 let len = read_len(r, major - 0x60)?;
468 let string = read_str(r, len as usize)?;
469 Self::String(string)
470 }
471
472 0x80..=0x9b => {
474 let len = read_len(r, major - 0x80)?;
475 let list = read_list(r, len as usize)?;
476 Self::List(list)
477 }
478
479 0x9f => {
481 let list = read_list_il(r)?;
482 Self::List(list)
483 }
484
485 0xa0..=0xbb => {
487 let len = read_len(r, major - 0xa0)?;
488 Self::Map(read_map(r, len as usize)?)
489 }
490
491 0xbf => Self::Map(read_map_il(r)?),
493
494 0xd8 => {
496 let tag = read_u8(r)?;
497 if tag == 42 {
498 Self::Link(read_link(r)?)
499 } else {
500 return Err(UnknownTag(tag).into());
501 }
502 }
503
504 0xf4 => Self::Bool(false),
506 0xf5 => Self::Bool(true),
507 0xf6 => Self::Null,
508 0xf7 => Self::Null,
509 0xfa => Self::Float(read_f32(r)? as f64),
510 0xfb => Self::Float(read_f64(r)?),
511 _ => return Err(UnexpectedCode::new::<Self>(major).into()),
512 };
513 Ok(ipld)
514 }
515}
516
517impl References<RawCborCodec> for Ipld {
518 fn references<R: Read + Seek, E: Extend<Cid>>(
519 c: RawCborCodec,
520 r: &mut R,
521 set: &mut E,
522 ) -> Result<()> {
523 let major = read_u8(r)?;
524 match major {
525 0x00..=0x17 => {}
527 0x18 => {
528 r.seek(SeekFrom::Current(1))?;
529 }
530 0x19 => {
531 r.seek(SeekFrom::Current(2))?;
532 }
533 0x1a => {
534 r.seek(SeekFrom::Current(4))?;
535 }
536 0x1b => {
537 r.seek(SeekFrom::Current(8))?;
538 }
539
540 0x20..=0x37 => {}
542 0x38 => {
543 r.seek(SeekFrom::Current(1))?;
544 }
545 0x39 => {
546 r.seek(SeekFrom::Current(2))?;
547 }
548 0x3a => {
549 r.seek(SeekFrom::Current(4))?;
550 }
551 0x3b => {
552 r.seek(SeekFrom::Current(8))?;
553 }
554
555 0x40..=0x5b => {
557 let len = read_len(r, major - 0x40)?;
558 r.seek(SeekFrom::Current(len as _))?;
559 }
560
561 0x60..=0x7b => {
563 let len = read_len(r, major - 0x60)?;
564 r.seek(SeekFrom::Current(len as _))?;
565 }
566
567 0x80..=0x9b => {
569 let len = read_len(r, major - 0x80)?;
570 for _ in 0..len {
571 <Self as References<RawCborCodec>>::references(c, r, set)?;
572 }
573 }
574
575 0x9f => loop {
577 let major = read_u8(r)?;
578 if major == 0xff {
579 break;
580 }
581 r.seek(SeekFrom::Current(-1))?;
582 <Self as References<RawCborCodec>>::references(c, r, set)?;
583 },
584
585 0xa0..=0xbb => {
587 let len = read_len(r, major - 0xa0)?;
588 for _ in 0..len {
589 <Self as References<RawCborCodec>>::references(c, r, set)?;
590 <Self as References<RawCborCodec>>::references(c, r, set)?;
591 }
592 }
593
594 0xbf => loop {
596 let major = read_u8(r)?;
597 if major == 0xff {
598 break;
599 }
600 r.seek(SeekFrom::Current(-1))?;
601 <Self as References<RawCborCodec>>::references(c, r, set)?;
602 <Self as References<RawCborCodec>>::references(c, r, set)?;
603 },
604
605 0xd8 => {
607 let tag = read_u8(r)?;
608 if tag == 42 {
609 set.extend(std::iter::once(read_link(r)?));
610 } else {
611 <Self as References<RawCborCodec>>::references(c, r, set)?;
612 }
613 }
614
615 0xf4..=0xf7 => {}
617 0xf8 => {
618 r.seek(SeekFrom::Current(1))?;
619 }
620 0xf9 => {
621 r.seek(SeekFrom::Current(2))?;
622 }
623 0xfa => {
624 r.seek(SeekFrom::Current(4))?;
625 }
626 0xfb => {
627 r.seek(SeekFrom::Current(8))?;
628 }
629 major => return Err(UnexpectedCode::new::<Ipld>(major).into()),
630 };
631 Ok(())
632 }
633}
634
635impl<T: Decode<RawCborCodec>> Decode<RawCborCodec> for Arc<T> {
636 fn decode<R: Read + Seek>(c: RawCborCodec, r: &mut R) -> Result<Self> {
637 Ok(Arc::new(T::decode(c, r)?))
638 }
639}
640
641impl Decode<RawCborCodec> for () {
642 fn decode<R: Read + Seek>(_c: RawCborCodec, r: &mut R) -> Result<Self> {
643 let major = read_u8(r)?;
644 match major {
645 0x80 => {}
646 _ => {
647 return Err(UnexpectedCode::new::<Self>(major).into());
648 }
649 };
650 Ok(())
651 }
652}
653
654impl<A: Decode<RawCborCodec>> Decode<RawCborCodec> for (A,) {
655 fn decode<R: Read + Seek>(c: RawCborCodec, r: &mut R) -> Result<Self> {
656 let major = read_u8(r)?;
657 let result = match major {
658 0x81 => (A::decode(c, r)?,),
659 _ => {
660 return Err(UnexpectedCode::new::<Self>(major).into());
661 }
662 };
663 Ok(result)
664 }
665}
666
667impl<A: Decode<RawCborCodec>, B: Decode<RawCborCodec>> Decode<RawCborCodec> for (A, B) {
668 fn decode<R: Read + Seek>(c: RawCborCodec, r: &mut R) -> Result<Self> {
669 let major = read_u8(r)?;
670 let result = match major {
671 0x82 => (A::decode(c, r)?, B::decode(c, r)?),
672 _ => {
673 return Err(UnexpectedCode::new::<Self>(major).into());
674 }
675 };
676 Ok(result)
677 }
678}
679
680impl<A: Decode<RawCborCodec>, B: Decode<RawCborCodec>, C: Decode<RawCborCodec>> Decode<RawCborCodec>
681 for (A, B, C)
682{
683 fn decode<R: Read + Seek>(c: RawCborCodec, r: &mut R) -> Result<Self> {
684 let major = read_u8(r)?;
685 let result = match major {
686 0x83 => (A::decode(c, r)?, B::decode(c, r)?, C::decode(c, r)?),
687 _ => {
688 return Err(UnexpectedCode::new::<Self>(major).into());
689 }
690 };
691 Ok(result)
692 }
693}
694
695impl<A: Decode<RawCborCodec>, B: Decode<RawCborCodec>, C: Decode<RawCborCodec>, D: Decode<RawCborCodec>>
696 Decode<RawCborCodec> for (A, B, C, D)
697{
698 fn decode<R: Read + Seek>(c: RawCborCodec, r: &mut R) -> Result<Self> {
699 let major = read_u8(r)?;
700 let result = match major {
701 0x84 => (
702 A::decode(c, r)?,
703 B::decode(c, r)?,
704 C::decode(c, r)?,
705 D::decode(c, r)?,
706 ),
707 _ => {
708 return Err(UnexpectedCode::new::<Self>(major).into());
709 }
710 };
711 Ok(result)
712 }
713}
714
715impl SkipOne for RawCborCodec {
716 fn skip<R: Read + Seek>(&self, r: &mut R) -> Result<()> {
717 let major = read_u8(r)?;
718 match major {
719 0x00..=0x17 => {}
721 0x18 => {
722 r.seek(SeekFrom::Current(1))?;
723 }
724 0x19 => {
725 r.seek(SeekFrom::Current(2))?;
726 }
727 0x1a => {
728 r.seek(SeekFrom::Current(4))?;
729 }
730 0x1b => {
731 r.seek(SeekFrom::Current(8))?;
732 }
733
734 0x20..=0x37 => {}
736 0x38 => {
737 r.seek(SeekFrom::Current(1))?;
738 }
739 0x39 => {
740 r.seek(SeekFrom::Current(2))?;
741 }
742 0x3a => {
743 r.seek(SeekFrom::Current(4))?;
744 }
745 0x3b => {
746 r.seek(SeekFrom::Current(8))?;
747 }
748
749 0x40..=0x5b => {
751 let len = read_len(r, major - 0x40)?;
752 r.seek(SeekFrom::Current(len as _))?;
753 }
754
755 0x60..=0x7b => {
757 let len = read_len(r, major - 0x60)?;
758 r.seek(SeekFrom::Current(len as _))?;
759 }
760
761 0x80..=0x9b => {
763 let len = read_len(r, major - 0x80)?;
764 for _ in 0..len {
765 self.skip(r)?;
766 }
767 }
768
769 0x9f => loop {
771 let major = read_u8(r)?;
772 if major == 0xff {
773 break;
774 }
775 r.seek(SeekFrom::Current(-1))?;
776 self.skip(r)?;
777 },
778
779 0xa0..=0xbb => {
781 let len = read_len(r, major - 0xa0)?;
782 for _ in 0..len {
783 self.skip(r)?;
784 self.skip(r)?;
785 }
786 }
787
788 0xbf => loop {
790 let major = read_u8(r)?;
791 if major == 0xff {
792 break;
793 }
794 r.seek(SeekFrom::Current(-1))?;
795 self.skip(r)?;
796 self.skip(r)?;
797 },
798
799 0xc0..=0xd7 => {
801 self.skip(r)?;
803 }
804 0xd8 => {
805 r.seek(SeekFrom::Current(1))?;
806 self.skip(r)?;
807 }
808
809 0xd9 => {
810 r.seek(SeekFrom::Current(2))?;
811 self.skip(r)?;
812 }
813 0xda => {
814 r.seek(SeekFrom::Current(4))?;
815 self.skip(r)?;
816 }
817 0xdb => {
818 r.seek(SeekFrom::Current(8))?;
819 self.skip(r)?;
820 }
821
822 0xf4..=0xf7 => {}
824 0xf8 => {
825 r.seek(SeekFrom::Current(1))?;
826 }
827 0xf9 => {
828 r.seek(SeekFrom::Current(2))?;
829 }
830 0xfa => {
831 r.seek(SeekFrom::Current(4))?;
832 }
833 0xfb => {
834 r.seek(SeekFrom::Current(8))?;
835 }
836 major => return Err(UnexpectedCode::new::<Ipld>(major).into()),
837 };
838 Ok(())
839 }
840}
841
842#[cfg(test)]
843mod tests {
844 use super::*;
845 use crate::{error::UnexpectedEof, RawCborCodec};
846 use libipld_core::codec::Codec;
847 use libipld_macro::ipld;
848
849 #[test]
850 fn il_map() {
851 let bytes = [
852 0xBF, 0x63, 0x46, 0x75, 0x6e, 0xF5, 0x63, 0x41, 0x6d, 0x74, 0x21, 0xFF, ];
861 let ipld = ipld!({
862 "Fun": true,
863 "Amt": -2,
864 });
865 let ipld2: Ipld = RawCborCodec.decode(&bytes).unwrap();
866 assert_eq!(ipld, ipld2);
867 }
868
869 #[test]
870 fn bad_list() {
871 let bytes = [
872 0x5b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, ];
876 RawCborCodec
877 .decode::<Ipld>(&bytes)
878 .expect_err("decoding large truncated buffer should have failed")
879 .downcast::<UnexpectedEof>()
880 .expect("expected an unexpected eof");
881 }
882
883 #[test]
884 #[allow(clippy::let_unit_value)]
885 fn tuples() -> Result<()> {
886 let data = ();
887 let bytes = RawCborCodec.encode(&data)?;
888 let _data2: () = RawCborCodec.decode(&bytes)?;
889
890 let data = ("hello".to_string(),);
891 let bytes = RawCborCodec.encode(&data)?;
892 let data2: (String,) = RawCborCodec.decode(&bytes)?;
893 assert_eq!(data, data2);
894
895 let data = ("hello".to_string(), "world".to_string());
896 let bytes = RawCborCodec.encode(&data)?;
897 let data2: (String, String) = RawCborCodec.decode(&bytes)?;
898 assert_eq!(data, data2);
899
900 let data = ("hello".to_string(), "world".to_string(), 42);
901 let bytes = RawCborCodec.encode(&data)?;
902 let data2: (String, String, u32) = RawCborCodec.decode(&bytes)?;
903 assert_eq!(data, data2);
904
905 let data = ("hello".to_string(), "world".to_string(), 42, 64);
906 let bytes = RawCborCodec.encode(&data)?;
907 let data2: (String, String, u32, u8) = RawCborCodec.decode(&bytes)?;
908 assert_eq!(data, data2);
909
910 Ok(())
911 }
912}