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