rusmpp_core/decode/owned.rs
1//! Traits for decoding `SMPP` values with owned data.
2//!
3use crate::decode::DecodeError;
4
5/// Trait for decoding `SMPP` values from a slice.
6///
7/// # Implementation
8///
9/// ```rust
10/// # use rusmpp_core::decode::{owned::Decode, DecodeError};
11///
12/// #[derive(Debug, PartialEq, Eq)]
13/// struct Foo {
14/// a: u8,
15/// b: u16,
16/// c: u32,
17/// }
18///
19/// impl Decode for Foo {
20/// fn decode(src: &[u8]) -> Result<(Self, usize), DecodeError> {
21/// let index = 0;
22///
23/// let (a, size) = Decode::decode(&src[index..])?;
24/// let index = index + size;
25///
26/// let (b, size) = Decode::decode(&src[index..])?;
27/// let index = index + size;
28///
29/// let (c, size) = Decode::decode(&src[index..])?;
30/// let index = index + size;
31///
32/// Ok((Foo { a, b, c }, index))
33/// }
34/// }
35///
36/// let buf = &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
37///
38/// let expected = Foo {
39/// a: 0x01,
40/// b: 0x0203,
41/// c: 0x04050607,
42/// };
43///
44/// let (foo, size) = Foo::decode(buf).unwrap();
45///
46/// assert_eq!(size, 7);
47/// assert_eq!(foo, expected);
48/// assert_eq!(&buf[size..], &[0x08]);
49/// ```
50pub trait Decode: Sized {
51 /// Decode a value from a slice.
52 fn decode(src: &[u8]) -> Result<(Self, usize), DecodeError>;
53}
54
55/// Trait for decoding `SMPP` values from a slice with a specified length.
56///
57/// # Implementation
58///
59/// ```rust
60/// # #[cfg(feature = "alloc")]
61/// # {
62/// # use rusmpp_core::{
63/// # decode::{owned::{Decode, DecodeWithLength}, DecodeError},
64/// # types::owned::AnyOctetString,
65/// # };
66///
67/// #[derive(Debug, PartialEq, Eq)]
68/// struct Foo {
69/// a: u8,
70/// b: u16,
71/// c: AnyOctetString,
72/// }
73///
74/// impl DecodeWithLength for Foo {
75/// fn decode(src: &[u8], length: usize) -> Result<(Self, usize), DecodeError> {
76/// let index = 0;
77///
78/// let (a, size) = Decode::decode(&src[index..])?;
79/// let index = index + size;
80///
81/// let (b, size) = Decode::decode(&src[index..])?;
82/// let index = index + size;
83///
84/// let (c, size) = AnyOctetString::decode(&src[index..], length - index)?;
85/// let index = index + size;
86///
87/// Ok((Foo { a, b, c }, index))
88/// }
89/// }
90///
91/// // Received over the wire
92/// let length = 8;
93///
94/// let buf = &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
95///
96/// let expected = Foo {
97/// a: 0x01,
98/// b: 0x0203,
99/// c: AnyOctetString::new([0x04, 0x05, 0x06, 0x07, 0x08]),
100/// };
101///
102/// let (foo, size) = Foo::decode(buf, length).unwrap();
103///
104/// assert_eq!(size, 8);
105/// assert_eq!(foo, expected);
106/// assert_eq!(&buf[size..], &[0x09]);
107/// # }
108/// ```
109pub trait DecodeWithLength: Sized {
110 /// Decode a value from a slice, with a specified length
111 fn decode(src: &[u8], length: usize) -> Result<(Self, usize), DecodeError>;
112}
113
114/// Everything that implements [`Decode`] also implements [`DecodeWithLength`] by ignoring the length.
115impl<T: Decode> DecodeWithLength for T {
116 fn decode(src: &[u8], _length: usize) -> Result<(Self, usize), DecodeError> {
117 Decode::decode(src)
118 }
119}
120
121/// Trait for decoding `SMPP` values from a slice with a specified key and length.
122///
123/// # Implementation
124///
125/// ```rust
126/// # #[cfg(feature = "alloc")]
127/// # {
128/// # use rusmpp_core::{
129/// # decode::{owned::{Decode, DecodeWithKey, DecodeWithLength}, DecodeError},
130/// # types::owned::AnyOctetString,
131/// # };
132///
133/// #[derive(Debug, PartialEq, Eq)]
134/// enum Foo {
135/// A(u16),
136/// B(AnyOctetString),
137/// }
138///
139/// impl DecodeWithKey for Foo {
140/// type Key = u32;
141///
142/// fn decode(key: Self::Key, src: &[u8], length: usize) -> Result<(Self, usize), DecodeError> {
143/// match key {
144/// 0x01020304 => {
145/// let (a, size) = Decode::decode(src)?;
146///
147/// Ok((Foo::A(a), size))
148/// }
149/// 0x04030201 => {
150/// let (b, size) = AnyOctetString::decode(src, length)?;
151///
152/// Ok((Foo::B(b), size))
153/// }
154/// _ => Err(DecodeError::unsupported_key(key)),
155/// }
156/// }
157/// }
158///
159/// // Received over the wire
160/// let length = 8;
161///
162/// // Key is A
163/// let buf = &[
164/// 0x01, 0x02, 0x03, 0x04, // Key
165/// 0x05, 0x06, // Value
166/// 0x07, 0x08, 0x09, 0x0A, 0x0B, // Rest
167/// ];
168///
169/// let index = 0;
170///
171/// let (key, size) = Decode::decode(buf).unwrap();
172/// let index = index + size;
173///
174/// let (foo, size) = Foo::decode(key, &buf[index..], length - index).unwrap();
175/// let index = index + size;
176///
177/// let expected = Foo::A(0x0506);
178///
179/// assert_eq!(size, 2);
180/// assert_eq!(foo, expected);
181/// assert_eq!(&buf[index..], &[0x07, 0x08, 0x09, 0x0A, 0x0B]);
182///
183/// // Received over the wire
184/// let length = 8;
185///
186/// // Key is B
187/// let buf = &[
188/// 0x04, 0x03, 0x02, 0x01, // Key
189/// 0x05, 0x06, 0x07, 0x08, // Value
190/// 0x09, 0x0A, 0x0B, // Rest
191/// ];
192///
193/// let index = 0;
194///
195/// let (key, size) = Decode::decode(buf).unwrap();
196/// let index = index + size;
197///
198/// let (foo, size) = Foo::decode(key, &buf[index..], length - index).unwrap();
199/// let index = index + size;
200///
201/// let expected = Foo::B(AnyOctetString::new([0x05, 0x06, 0x07, 0x08]));
202///
203/// assert_eq!(size, 4);
204/// assert_eq!(foo, expected);
205/// assert_eq!(&buf[index..], &[0x09, 0x0A, 0x0B]);
206/// # }
207/// ```
208pub trait DecodeWithKey: Sized {
209 type Key;
210
211 /// Decode a value from a slice, using a key to determine the type.
212 fn decode(key: Self::Key, src: &[u8], length: usize) -> Result<(Self, usize), DecodeError>;
213}
214
215/// Trait for decoding optional `SMPP` values from a slice with a specified key and length.
216///
217/// # Implementation
218///
219/// ```rust
220/// # #[cfg(feature = "alloc")]
221/// # {
222/// # use rusmpp_core::{
223/// # decode::{owned::{Decode, DecodeWithKeyOptional, DecodeWithLength}, DecodeError},
224/// # types::owned::AnyOctetString,
225/// # };
226///
227/// #[derive(Debug, PartialEq, Eq)]
228/// enum Foo {
229/// A,
230/// B(u16),
231/// C(AnyOctetString),
232/// }
233///
234/// impl DecodeWithKeyOptional for Foo {
235/// type Key = u32;
236///
237/// fn decode(
238/// key: Self::Key,
239/// src: &[u8],
240/// length: usize,
241/// ) -> Result<Option<(Self, usize)>, DecodeError> {
242/// if length == 0 {
243/// match key {
244/// 0x00000000 => return Ok(Some((Foo::A, 0))),
245/// _ => return Ok(None),
246/// }
247/// }
248///
249/// match key {
250/// 0x01020304 => {
251/// let (a, size) = Decode::decode(src)?;
252///
253/// Ok(Some((Foo::B(a), size)))
254/// }
255/// 0x04030201 => {
256/// let (b, size) = AnyOctetString::decode(src, length)?;
257///
258/// Ok(Some((Foo::C(b), size)))
259/// }
260/// _ => Err(DecodeError::unsupported_key(key)),
261/// }
262/// }
263/// }
264///
265/// // Received over the wire
266/// let length = 4;
267///
268/// // Key is A
269/// let buf = &[
270/// 0x00, 0x00, 0x00, 0x00, // Key
271/// 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, // Rest
272/// ];
273///
274/// let index = 0;
275///
276/// let (key, size) = Decode::decode(buf).unwrap();
277/// let index = index + size;
278///
279/// let (foo, size) = Foo::decode(key, &buf[index..], length - index)
280/// .unwrap()
281/// .unwrap();
282/// let index = index + size;
283///
284/// let expected = Foo::A;
285///
286/// assert_eq!(size, 0);
287/// assert_eq!(foo, expected);
288/// assert_eq!(&buf[index..], &[0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B]);
289///
290/// // Received over the wire
291/// let length = 4;
292///
293/// // Key is B, but the received length indicates no value
294/// let buf = &[
295/// 0x01, 0x02, 0x03, 0x04, // Key
296/// 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, // Rest
297/// ];
298///
299/// let index = 0;
300///
301/// let (key, size) = Decode::decode(buf).unwrap();
302/// let index = index + size;
303///
304/// let value = Foo::decode(key, &buf[index..], length - index).unwrap();
305///
306/// assert!(value.is_none());
307/// assert_eq!(&buf[index..], &[0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B]);
308///
309/// // Received over the wire
310/// let length = 8;
311///
312/// // Key is B
313/// let buf = &[
314/// 0x01, 0x02, 0x03, 0x04, // Key
315/// 0x05, 0x06, // Value
316/// 0x07, 0x08, 0x09, 0x0A, 0x0B, // Rest
317/// ];
318///
319/// let index = 0;
320///
321/// let (key, size) = Decode::decode(buf).unwrap();
322/// let index = index + size;
323///
324/// let (foo, size) = Foo::decode(key, &buf[index..], length - index)
325/// .unwrap()
326/// .unwrap();
327/// let index = index + size;
328///
329/// let expected = Foo::B(0x0506);
330///
331/// assert_eq!(size, 2);
332/// assert_eq!(foo, expected);
333/// assert_eq!(&buf[index..], &[0x07, 0x08, 0x09, 0x0A, 0x0B]);
334///
335/// // Received over the wire
336/// let length = 8;
337///
338/// // Key is C
339/// let buf = &[
340/// 0x04, 0x03, 0x02, 0x01, // Key
341/// 0x05, 0x06, 0x07, 0x08, // Value
342/// 0x09, 0x0A, 0x0B, // Rest
343/// ];
344///
345/// let index = 0;
346///
347/// let (key, size) = Decode::decode(buf).unwrap();
348/// let index = index + size;
349///
350/// let (foo, size) = Foo::decode(key, &buf[index..], length - index)
351/// .unwrap()
352/// .unwrap();
353/// let index = index + size;
354///
355/// let expected = Foo::C(AnyOctetString::new([0x05, 0x06, 0x07, 0x08]));
356///
357/// assert_eq!(size, 4);
358/// assert_eq!(foo, expected);
359/// assert_eq!(&buf[index..], &[0x09, 0x0A, 0x0B]);
360/// # }
361/// ```
362pub trait DecodeWithKeyOptional: Sized {
363 type Key;
364
365 /// Decode an optional value from a slice, using a key to determine the type.
366 fn decode(
367 key: Self::Key,
368 src: &[u8],
369 length: usize,
370 ) -> Result<Option<(Self, usize)>, DecodeError>;
371}
372
373#[doc(hidden)]
374pub trait DecodeExt: Decode {
375 fn decode_move(src: &[u8], size: usize) -> Result<(Self, usize), DecodeError> {
376 Self::decode(&src[size..]).map(|(this, size_)| (this, size + size_))
377 }
378
379 /// Decode a vector of values from a slice with a specified count.
380 #[cfg(any(test, feature = "alloc"))]
381 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
382 fn counted(src: &[u8], count: usize) -> Result<(alloc::vec::Vec<Self>, usize), DecodeError> {
383 (0..count).try_fold(
384 (alloc::vec::Vec::with_capacity(count), 0),
385 |(mut vec, size), _| {
386 Self::decode(&src[size..]).map(|(item, size_)| {
387 vec.push(item);
388
389 (vec, size + size_)
390 })
391 },
392 )
393 }
394
395 #[cfg(any(test, feature = "alloc"))]
396 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
397 fn counted_move(
398 src: &[u8],
399 count: usize,
400 size: usize,
401 ) -> Result<(alloc::vec::Vec<Self>, usize), DecodeError> {
402 Self::counted(&src[size..], count).map(|(vec, size_)| (vec, size + size_))
403 }
404
405 /// Decode a value from a slice.
406 ///
407 /// If the length is 0, return `None`.
408 fn length_checked_decode(
409 src: &[u8],
410 length: usize,
411 ) -> Result<Option<(Self, usize)>, DecodeError> {
412 (length > 0)
413 .then_some(())
414 .map(|_| Self::decode(src))
415 .transpose()
416 }
417
418 fn length_checked_decode_move(
419 src: &[u8],
420 length: usize,
421 size: usize,
422 ) -> Result<Option<(Self, usize)>, DecodeError> {
423 Self::length_checked_decode(&src[size..], length)
424 .map(|decoded| decoded.map(|(this, size_)| (this, size + size_)))
425 }
426}
427
428impl<T: Decode> DecodeExt for T {}
429
430#[doc(hidden)]
431pub trait DecodeWithLengthExt: DecodeWithLength {
432 fn decode_move(src: &[u8], length: usize, size: usize) -> Result<(Self, usize), DecodeError> {
433 Self::decode(&src[size..], length).map(|(this, size_)| (this, size + size_))
434 }
435}
436
437impl<T: DecodeWithLength> DecodeWithLengthExt for T {}
438
439#[doc(hidden)]
440pub trait DecodeWithKeyExt: DecodeWithKey {
441 /// Decode a value from a slice, using a key to determine the type.
442 ///
443 /// If the length is 0, return `None`.
444 fn optional_length_checked_decode(
445 key: Self::Key,
446 src: &[u8],
447 length: usize,
448 ) -> Result<Option<(Self, usize)>, DecodeError> {
449 (length > 0)
450 .then_some(())
451 .map(|_| Self::decode(key, src, length))
452 .transpose()
453 }
454
455 fn optional_length_checked_decode_move(
456 key: Self::Key,
457 src: &[u8],
458 length: usize,
459 size: usize,
460 ) -> Result<Option<(Self, usize)>, DecodeError> {
461 Self::optional_length_checked_decode(key, &src[size..], length)
462 .map(|decoded| decoded.map(|(this, size_)| (this, size + size_)))
463 }
464}
465
466impl<T: DecodeWithKey> DecodeWithKeyExt for T {}
467
468#[doc(hidden)]
469pub trait DecodeWithKeyOptionalExt: DecodeWithKeyOptional {
470 fn decode_move(
471 key: Self::Key,
472 src: &[u8],
473 length: usize,
474 size: usize,
475 ) -> Result<Option<(Self, usize)>, DecodeError> {
476 Self::decode(key, &src[size..], length)
477 .map(|decoded| decoded.map(|(this, size_)| (this, size + size_)))
478 }
479}
480
481impl<T: DecodeWithKeyOptional> DecodeWithKeyOptionalExt for T {}
482
483#[cfg(any(test, feature = "alloc"))]
484#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
485impl<T: Decode> DecodeWithLength for alloc::vec::Vec<T> {
486 fn decode(src: &[u8], length: usize) -> Result<(Self, usize), DecodeError> {
487 if length == 0 {
488 return Ok((alloc::vec::Vec::new(), 0));
489 }
490
491 if length > src.len() {
492 return Err(DecodeError::unexpected_eof());
493 }
494
495 let mut size = 0;
496
497 let mut vec = alloc::vec::Vec::new();
498
499 while size < length {
500 let (item, size_) = T::decode(&src[size..length])?;
501
502 size += size_;
503
504 vec.push(item);
505 }
506
507 Ok((vec, size))
508 }
509}
510
511// TODO: fuzz the decode functions
512#[cfg(test)]
513mod tests {
514
515 use alloc::vec::Vec;
516
517 use crate::{
518 decode::{COctetStringDecodeError, DecodeErrorKind},
519 types::owned::{COctetString, EmptyOrFullCOctetString},
520 };
521
522 use super::*;
523
524 /// Testing [`counted_move`](DecodeExt::counted_move) will automatically test [`counted`](DecodeExt::counted).
525 #[test]
526 fn counted_move() {
527 // Count is 0
528 let buf = &[0, 1, 2];
529
530 let (values, size) = u8::counted_move(buf, 0, 0).unwrap();
531
532 assert_eq!(size, 0);
533 assert_eq!(&buf[size..], &[0, 1, 2]);
534 assert_eq!(values, Vec::<u8>::new());
535
536 // Count is more than the buffer
537 let buf = &[0, 1, 2];
538
539 let error = u8::counted_move(buf, 5, 0).unwrap_err();
540 assert!(matches!(error.kind(), DecodeErrorKind::UnexpectedEof));
541
542 // Count is within the buffer
543 let buf = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
544
545 let (values, size) = u8::counted_move(buf, 10, 0).unwrap();
546
547 assert_eq!(size, 10);
548 assert!(&buf[size..].is_empty());
549 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
550
551 let buf = &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9];
552
553 let (values, size) = u16::counted_move(buf, 10, 0).unwrap();
554
555 assert_eq!(size, 20);
556 assert!(&buf[size..].is_empty());
557 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
558
559 let buf = &[
560 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0,
561 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9,
562 ];
563
564 // Actually 10 values, 12 will break
565 let error = u32::counted_move(buf, 12, 0).unwrap_err();
566
567 assert!(matches!(error.kind(), DecodeErrorKind::UnexpectedEof));
568
569 let buf = b"Hello\0World\0";
570
571 let (values, size) = COctetString::<1, 6>::counted_move(buf, 2, 0).unwrap();
572
573 assert_eq!(size, 12);
574 assert!(&buf[size..].is_empty());
575 assert_eq!(
576 values,
577 alloc::vec![
578 COctetString::<1, 6>::new(b"Hello\0").unwrap(),
579 COctetString::<1, 6>::new(b"World\0").unwrap(),
580 ]
581 );
582
583 let buf = b"Hello\0World\0";
584
585 let (values, size) = EmptyOrFullCOctetString::<6>::counted_move(buf, 2, 0).unwrap();
586
587 assert_eq!(size, 12);
588 assert!(&buf[size..].is_empty());
589 assert_eq!(
590 values,
591 alloc::vec![
592 EmptyOrFullCOctetString::<6>::new(b"Hello\0").unwrap(),
593 EmptyOrFullCOctetString::<6>::new(b"World\0").unwrap(),
594 ]
595 );
596
597 let buf = b"Hello\0World\0Hi";
598
599 let error = COctetString::<1, 6>::counted_move(buf, 3, 0).unwrap_err();
600
601 assert!(matches!(
602 error.kind(),
603 DecodeErrorKind::COctetStringDecodeError(COctetStringDecodeError::NotNullTerminated)
604 ));
605
606 // Remaining bytes
607 let buf = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
608
609 let (values, size) = u8::counted_move(buf, 5, 0).unwrap();
610
611 assert_eq!(size, 5);
612 assert_eq!(&buf[size..], &[5, 6, 7, 8, 9]);
613 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4]);
614
615 let buf = &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9];
616
617 let (values, size) = u16::counted_move(buf, 5, 0).unwrap();
618
619 assert_eq!(size, 10);
620 assert_eq!(&buf[size..], &[0, 5, 0, 6, 0, 7, 0, 8, 0, 9]);
621 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4]);
622 }
623
624 #[test]
625 fn decode_with_length_vec() {
626 // Length is 0
627 let buf = &[0, 1, 2];
628
629 let (values, size) = Vec::<u8>::decode(buf, 0).unwrap();
630
631 assert_eq!(size, 0);
632 assert_eq!(&buf[size..], &[0, 1, 2]);
633 assert_eq!(values, Vec::<u8>::new());
634
635 // Length is bigger than the buffer
636 let buf = &[0, 1, 2];
637
638 let error = Vec::<u8>::decode(buf, 5).unwrap_err();
639
640 assert!(matches!(error.kind(), DecodeErrorKind::UnexpectedEof));
641
642 // Length is within the buffer
643 let buf = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
644
645 let (values, size) = Vec::<u8>::decode(buf, 10).unwrap();
646
647 assert_eq!(size, 10);
648 assert!(&buf[size..].is_empty());
649 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
650
651 let buf = &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9];
652
653 let (values, size) = Vec::<u16>::decode(buf, 20).unwrap();
654
655 assert_eq!(size, 20);
656 assert!(&buf[size..].is_empty());
657 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
658
659 let buf = &[
660 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0,
661 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9,
662 ];
663
664 // Actually 40 bytes, 50 will break
665 let error = Vec::<u32>::decode(buf, 50).unwrap_err();
666
667 assert!(matches!(error.kind(), DecodeErrorKind::UnexpectedEof));
668
669 let buf = b"Hello\0World\0";
670
671 let (values, size) = Vec::<COctetString<1, 6>>::decode(buf, 12).unwrap();
672
673 assert_eq!(size, 12);
674 assert!(&buf[size..].is_empty());
675 assert_eq!(
676 values,
677 alloc::vec![
678 COctetString::<1, 6>::new(b"Hello\0").unwrap(),
679 COctetString::<1, 6>::new(b"World\0").unwrap(),
680 ]
681 );
682
683 let buf = b"Hello\0World\0";
684
685 let (values, size) = Vec::<EmptyOrFullCOctetString<6>>::decode(buf, 12).unwrap();
686
687 assert_eq!(size, 12);
688 assert!(&buf[size..].is_empty());
689 assert_eq!(
690 values,
691 alloc::vec![
692 EmptyOrFullCOctetString::<6>::new(b"Hello\0").unwrap(),
693 EmptyOrFullCOctetString::<6>::new(b"World\0").unwrap(),
694 ]
695 );
696
697 let buf = b"Hello\0World\0Hi";
698
699 // This will try to decode 11 bytes b"Hello\0World"
700 let error = Vec::<COctetString<1, 6>>::decode(buf, 11).unwrap_err();
701
702 assert!(matches!(
703 error.kind(),
704 DecodeErrorKind::COctetStringDecodeError(COctetStringDecodeError::NotNullTerminated)
705 ));
706
707 // Remaining bytes
708 let buf = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
709
710 let (values, size) = Vec::<u8>::decode(buf, 5).unwrap();
711
712 assert_eq!(size, 5);
713 assert_eq!(&buf[size..], &[5, 6, 7, 8, 9]);
714 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4]);
715
716 let buf = &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9];
717
718 let (values, size) = Vec::<u16>::decode(buf, 10).unwrap();
719
720 assert_eq!(size, 10);
721 assert_eq!(&buf[size..], &[0, 5, 0, 6, 0, 7, 0, 8, 0, 9]);
722 assert_eq!(values, alloc::vec![0, 1, 2, 3, 4]);
723 }
724}