encdec_base/decode/
owned.rs

1use core::fmt::Debug;
2
3use super::Decode;
4use crate::Error;
5
6/// Decode trait implemented for owned types
7///
8/// This allows eliding lifetime constraints for owned (ie. self-contained, not reference) types and provides a blanket [`Decode`] implementation
9pub trait DecodeOwned {
10    /// Output type
11    type Output: Debug;
12
13    /// Error type returned on parse error
14    type Error: From<Error> + Debug;
15
16    /// Decode consumes a slice and returns an object and decoded length.
17    fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error>;
18}
19
20/// Blanket [`Decode`] impl for [`DecodeOwned`] types
21impl<'a, T: DecodeOwned> Decode<'a> for T {
22    type Output = <T as DecodeOwned>::Output;
23
24    type Error = <T as DecodeOwned>::Error;
25
26    fn decode(buff: &'a [u8]) -> Result<(Self::Output, usize), Self::Error> {
27        <T as DecodeOwned>::decode_owned(buff)
28    }
29}
30
31#[cfg(not(feature = "nightly"))]
32impl<T, const N: usize> DecodeOwned for [T; N]
33where
34    T: DecodeOwned<Output = T> + Debug + Default + Copy,
35    <T as DecodeOwned>::Error: From<Error> + Debug,
36{
37    type Error = <T as DecodeOwned>::Error;
38    type Output = [<T as DecodeOwned>::Output; N];
39
40    fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
41        let mut data: [T; N] = [T::default(); N];
42
43        let mut offset = 0;
44        for value in data.iter_mut() {
45            let (output, length) = T::decode_owned(&buff[offset..])?;
46            offset += length;
47            *value = output;
48        }
49
50        Ok((data, offset))
51    }
52}
53
54/// [`DecodeOwned`] for `[T; N]`s containing [`DecodeOwned`] types
55#[cfg(feature = "nightly")]
56impl<T, const N: usize> DecodeOwned for [T; N]
57where
58    T: DecodeOwned<Output = T> + Debug,
59    <T as DecodeOwned>::Error: From<Error> + Debug,
60{
61    type Error = <T as DecodeOwned>::Error;
62
63    type Output = [<T as DecodeOwned>::Output; N];
64
65    fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
66        let mut index = 0;
67
68        let decoded = core::array::try_from_fn(|_i| match T::decode(&buff[index..]) {
69            Ok((o, l)) => {
70                index += l;
71                Ok(o)
72            }
73            Err(e) => Err(e),
74        })?;
75
76        Ok((decoded, index))
77    }
78}
79
80/// [`DecodeOwned`] for [`alloc::vec::Vec`]s containing [`DecodeOwned`] types
81#[cfg(feature = "alloc")]
82impl<T> DecodeOwned for alloc::vec::Vec<T>
83where
84    T: DecodeOwned<Output = T> + Debug,
85    <T as DecodeOwned>::Error: From<Error> + Debug,
86{
87    type Error = <T as DecodeOwned>::Error;
88
89    type Output = alloc::vec::Vec<<T as DecodeOwned>::Output>;
90
91    fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
92        let mut index = 0;
93        let mut v = alloc::vec::Vec::new();
94
95        while index < buff.len() {
96            let (d, n) = T::decode(&buff[index..])?;
97
98            v.push(d);
99            index += n;
100        }
101
102        Ok((v, index))
103    }
104}
105
106/// [`DecodeOwned`] for [`heapless::Vec`]s containing [`DecodeOwned`] types
107#[cfg(feature = "heapless")]
108impl<T, const N: usize> DecodeOwned for heapless::Vec<T, N>
109where
110    T: DecodeOwned<Output = T> + Debug,
111    <T as DecodeOwned>::Error: From<Error> + Debug,
112{
113    type Error = <T as DecodeOwned>::Error;
114
115    type Output = heapless::Vec<<T as DecodeOwned>::Output, N>;
116
117    fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
118        let mut index = 0;
119        let mut v = heapless::Vec::new();
120
121        while index < buff.len() {
122            let (d, n) = T::decode(&buff[index..])?;
123
124            if let Err(_e) = v.push(d) {
125                return Err(Error::Length.into());
126            }
127
128            index += n;
129        }
130
131        Ok((v, index))
132    }
133}