recode/codec/
buffer.rs

1use crate::bytes::{Buf, BufMut};
2use crate::{Decoder, Encoder, Error};
3
4/// A type alias for a [`Buffer`] without a length prefix.
5pub type UnprefixedBuffer = Buffer<crate::util::Remaining>;
6
7/// A wrapper type for consecutive bytes.
8///
9/// # Type Parameters
10/// - `L`: If not [`()`], it should be a numerical type that implements
11/// [`Decoder<Output = L`] and [`TryFrom<usize>`]` which represents the length
12/// prefix of the buffer.
13#[derive(Debug, Clone, Default)]
14pub struct Buffer<L> {
15    inner: bytes::Bytes,
16    _marker: std::marker::PhantomData<L>,
17}
18
19impl<L> Buffer<L> {
20    /// Creates a new [`Buffer<L>`] object from a [`bytes::Bytes`] instance.
21    ///
22    /// # Parameters
23    /// - `bytes`: The [`bytes::Bytes`] instance to wrap.
24    ///
25    /// # Returns
26    /// A new [`Buffer<L>`] object.
27    pub fn new(bytes: bytes::Bytes) -> Self {
28        Self {
29            inner: bytes,
30            _marker: Default::default(),
31        }
32    }
33
34    /// Creates a new [`Buffer<L>`] object from a [`&'static [u8]`].
35    ///
36    /// This is a shorthand for
37    /// [`Buffer::new`]`(`[`bytes::Bytes::from_static`]`(`[`&'static [u8]`]`))`.
38    ///
39    /// # Parameters
40    /// - `bytes`: The [`&'static [u8]`] instance to wrap.
41    ///
42    /// # Returns
43    /// A new [`Buffer<L>`] object.
44    pub fn from_static(bytes: &'static [u8]) -> Self {
45        Self::new(bytes.into())
46    }
47
48    /// Gets a reference to the inner [`bytes::Bytes`] instance.
49    pub const fn as_inner(&self) -> &bytes::Bytes {
50        &self.inner
51    }
52
53    /// Gets a mutable reference to the inner [`bytes::Bytes`] instance.
54    pub fn as_inner_mut(&mut self) -> &mut bytes::Bytes {
55        &mut self.inner
56    }
57
58    /// Consumes the [`Buffer<L>`] object and returns the inner
59    /// [`bytes::Bytes`] instance.
60    pub fn into_inner(self) -> bytes::Bytes {
61        self.inner
62    }
63}
64
65impl<B, L> Decoder<B> for Buffer<L>
66where
67    B: Buf,
68    L: Decoder<B, usize>,
69    Error: From<<L as Decoder<B, usize>>::Error>,
70{
71    type Error = Error;
72
73    fn decode(buf: &mut B) -> Result<Self, Self::Error> {
74        let len = L::decode(buf)?;
75
76        if buf.remaining() < len {
77            return Err(Error::BytesNeeded {
78                needed: len - buf.remaining(),
79                full_len: len,
80                available: buf.remaining(),
81            });
82        }
83
84        Ok(Self::new(buf.copy_to_bytes(len)))
85    }
86}
87
88impl<B, L> Encoder<B> for Buffer<L>
89where
90    B: BufMut,
91    L: Encoder<B, usize>,
92    Error: From<<L as Encoder<B, usize>>::Error>,
93{
94    type Error = Error;
95
96    fn encode(item: &Self, buf: &mut B) -> Result<(), Self::Error> {
97        let len = item.inner.len();
98
99        L::encode(&len, buf)?;
100        buf.put(item.inner.as_ref());
101
102        Ok(())
103    }
104
105    #[inline]
106    fn size_of(item: &Self, buf: &B) -> usize {
107        L::size_of(&item.inner.len(), buf) + item.inner.len()
108    }
109}
110
111impl<L> std::ops::Deref for Buffer<L> {
112    type Target = [u8];
113
114    fn deref(&self) -> &Self::Target {
115        self.inner.as_ref()
116    }
117}
118
119impl<L> From<&'static [u8]> for Buffer<L> {
120    #[inline(always)]
121    fn from(value: &'static [u8]) -> Self {
122        Self::from_static(value)
123    }
124}
125
126impl<L> From<bytes::Bytes> for Buffer<L> {
127    #[inline(always)]
128    fn from(value: bytes::Bytes) -> Self {
129        Self::new(value)
130    }
131}
132
133#[cfg(test)]
134mod tests {
135    use bytes::{Bytes, BytesMut};
136    use fake::{Fake, Faker};
137
138    #[cfg(all(test, feature = "ux"))]
139    use crate::codec::ux::*;
140
141    use crate::codec::*;
142    use crate::util::EncoderExt;
143    use crate::*;
144
145    #[test]
146    fn unprefixed_decode_test() {
147        let len: usize = (128..=10240).fake();
148        let bytes = BytesMut::from_iter((0..len).map(|_| Faker.fake::<u8>()));
149
150        assert_eq!(len, bytes.len());
151
152        let buffer = UnprefixedBuffer::decode(&mut bytes.clone()).unwrap();
153
154        assert_eq!(buffer.len(), len);
155        assert_eq!(buffer.as_ref(), bytes.as_ref());
156        assert_eq!(buffer.size(&bytes), len);
157
158        let mut encoded = BytesMut::new();
159        buffer.encode_to(&mut encoded).unwrap();
160
161        assert_eq!(encoded.len(), len);
162        assert_eq!(encoded.as_ref(), buffer.as_ref());
163    }
164
165    #[test]
166    fn whole_prefix_test() {
167        let full_len: usize = (128..=10240).fake();
168        let use_len: usize = (0..full_len).fake();
169        let pool = Bytes::from_iter((0..full_len).map(|_| Faker.fake::<u8>()));
170
171        assert!(use_len < full_len);
172        assert!(pool.len() == full_len);
173
174        let buffer = super::Buffer::<u32>::new(pool.slice(0..use_len));
175        let mut bytes = BytesMut::new();
176
177        buffer.encode_to(&mut bytes).unwrap();
178
179        assert_eq!(
180            buffer.size(&bytes),
181            buffer.len() + u32::size_of(&buffer.len(), &bytes)
182        );
183
184        assert_eq!(buffer.len(), use_len);
185        assert_eq!(bytes.len(), 4 + use_len);
186        assert_eq!((use_len as u32).to_be_bytes(), bytes[..4]);
187        assert_eq!(buffer.as_ref(), bytes[4..].as_ref());
188
189        let decoded = Buffer::<u32>::decode(&mut bytes).unwrap();
190
191        assert_eq!(decoded.len(), use_len);
192        assert_eq!(decoded.as_ref(), buffer.as_ref());
193    }
194
195    macro_rules! test_ux_len {
196        ($t:ty; size: $s:literal; rep: $r:ty ) => {
197            paste::paste! {
198                #[test]
199                #[cfg(all(test, feature = "ux"))]
200                fn [<sub_prefix_test_ $t>]() {
201                    const REPR_LEN: usize = std::mem::size_of::<$r>();
202
203                    let max: usize = <$t>::MAX.try_into().unwrap();
204                    let full_len: usize =
205                        (128..=std::cmp::min(10240usize, max)).fake();
206                    let use_len: usize = (0..full_len).fake();
207                    let pool =
208                        Bytes::from_iter((0..full_len).map(|_| Faker.fake::<u8>()));
209
210                    assert!(use_len < full_len);
211                    assert!(pool.len() == full_len);
212
213                    let buffer = super::Buffer::<$t>::new(pool.slice(0..use_len));
214                    let mut bytes = BytesMut::new();
215
216                    assert_eq!(
217                        buffer.size(&bytes),
218                        buffer.len() + <$t>::size_of(&buffer.len(), &bytes)
219                    );
220
221                    buffer.encode_to(&mut bytes).unwrap();
222
223                    let len_bytes = &(use_len as $r).to_be_bytes()[(REPR_LEN - $s)..];
224
225                    assert_eq!(buffer.len(), use_len);
226                    assert_eq!(bytes.len(), $s + use_len);
227                    assert_eq!(len_bytes, &bytes[0..$s]);
228                    assert_eq!(buffer.as_ref(), bytes[$s..].as_ref());
229
230                    let decoded = Buffer::<$t>::decode(&mut bytes).unwrap();
231
232                    assert_eq!(decoded.len(), use_len);
233                    assert_eq!(decoded.as_ref(), buffer.as_ref());
234                }
235            }
236        };
237    }
238
239    test_ux_len!(u24; size: 3; rep: u32);
240    test_ux_len!(u40; size: 5; rep: u64);
241    test_ux_len!(u48; size: 6; rep: u64);
242    test_ux_len!(u56; size: 7; rep: u64);
243}