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