bytes_varint/
try_get_fixed.rs

1//! Extends the `bytes` crate with functions to read fixed-length numbers wrapped in buffer
2//!  underflow checks. This is often useful when working with variable-length encoded buffers.
3//!
4//! This is in a separate module to make it easy to ignore when it is not needed.
5
6macro_rules! get_try_impl {
7    ($try_getter: ident, $ty:ty, $getter: ident) => {
8        /// Get a fixed-length encoded number, checking for buffer underflow.
9        fn $try_getter(&mut self) -> $crate::VarIntResult<$ty> {
10            if self.remaining() < size_of::<$ty>() {
11                return Err($crate::VarIntError::BufferUnderflow);
12            }
13            Ok(self.$getter())
14        }
15    }
16}
17
18
19/// When working with variable-length encodings for numbers, the buffers themselves become
20///  variable length, and it is impossible to check that they are long enough before decoding
21///  them. Fixed-length buffer layouts have obvious benefits, but if some protocol uses var-length
22///  encoding, buffer underflow can occur even when reading fixed-length numbers.
23///
24/// This trait provides functionality for decoding numbers using fixed-length encodings, but
25///  checking for buffer underflow.
26pub trait TryGetFixedSupport: bytes::Buf {
27    get_try_impl!(try_get_u8, u8, get_u8);
28
29    get_try_impl!(try_get_u16, u16, get_u16);
30    get_try_impl!(try_get_u32, u32, get_u32);
31    get_try_impl!(try_get_u64, u64, get_u64);
32    get_try_impl!(try_get_u128, u128, get_u128);
33
34    get_try_impl!(try_get_u16_le, u16, get_u16_le);
35    get_try_impl!(try_get_u32_le, u32, get_u32_le);
36    get_try_impl!(try_get_u64_le, u64, get_u64_le);
37    get_try_impl!(try_get_u128_le, u128, get_u128_le);
38
39    get_try_impl!(try_get_i8, i8, get_i8);
40
41    get_try_impl!(try_get_i16, i16, get_i16);
42    get_try_impl!(try_get_i32, i32, get_i32);
43    get_try_impl!(try_get_i64, i64, get_i64);
44    get_try_impl!(try_get_i128, i128, get_i128);
45
46    get_try_impl!(try_get_i16_le, i16, get_i16_le);
47    get_try_impl!(try_get_i32_le, i32, get_i32_le);
48    get_try_impl!(try_get_i64_le, i64, get_i64_le);
49    get_try_impl!(try_get_i128_le, i128, get_i128_le);
50}
51
52impl<T: bytes::Buf> TryGetFixedSupport for T {}
53
54#[cfg(test)]
55mod test {
56    extern crate alloc;
57
58    use alloc::vec;
59    use alloc::vec::Vec;
60
61    use rstest::rstest;
62
63    use crate::try_get_fixed::TryGetFixedSupport;
64    use crate::{VarIntResult, VarIntError};
65
66    #[rstest]
67    #[case(vec![1u8], Ok(1))]
68    #[case(vec![], Err(VarIntError::BufferUnderflow))]
69    fn test_u8(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u8>) {
70        let mut buf: &[u8] = &mut bytes;
71        assert_eq!(buf.try_get_u8(), expected);
72    }
73
74    #[rstest]
75    #[case(vec![1u8, 2u8], Ok(0x0102))]
76    #[case(vec![1u8], Err(VarIntError::BufferUnderflow))]
77    #[case(vec![], Err(VarIntError::BufferUnderflow))]
78    fn test_u16(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u16>) {
79        let mut buf: &[u8] = &mut bytes;
80        assert_eq!(buf.try_get_u16(), expected);
81    }
82    #[rstest]
83    #[case(vec![1u8, 2u8], Ok(0x0201))]
84    #[case(vec![1u8], Err(VarIntError::BufferUnderflow))]
85    #[case(vec![], Err(VarIntError::BufferUnderflow))]
86    fn test_u16_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u16>) {
87        let mut buf: &[u8] = &mut bytes;
88        assert_eq!(buf.try_get_u16_le(), expected);
89    }
90
91    #[rstest]
92    #[case(vec![1u8, 2u8, 3u8, 4u8], Ok(0x01020304))]
93    #[case(vec![1u8, 2u8, 3u8], Err(VarIntError::BufferUnderflow))]
94    #[case(vec![], Err(VarIntError::BufferUnderflow))]
95    fn test_u32(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u32>) {
96        let mut buf: &[u8] = &mut bytes;
97        assert_eq!(buf.try_get_u32(), expected);
98    }
99    #[rstest]
100    #[case(vec![1u8, 2u8, 3u8, 4u8], Ok(0x04030201))]
101    #[case(vec![1u8, 2u8, 3u8], Err(VarIntError::BufferUnderflow))]
102    #[case(vec![], Err(VarIntError::BufferUnderflow))]
103    fn test_u32_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u32>) {
104        let mut buf: &[u8] = &mut bytes;
105        assert_eq!(buf.try_get_u32_le(), expected);
106    }
107
108    #[rstest]
109    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8], Ok(0x0102030405060708))]
110    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8], Err(VarIntError::BufferUnderflow))]
111    #[case(vec![], Err(VarIntError::BufferUnderflow))]
112    fn test_u64(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u64>) {
113        let mut buf: &[u8] = &mut bytes;
114        assert_eq!(buf.try_get_u64(), expected);
115    }
116    #[rstest]
117    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8], Ok(0x0807060504030201))]
118    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8], Err(VarIntError::BufferUnderflow))]
119    #[case(vec![], Err(VarIntError::BufferUnderflow))]
120    fn test_u64_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u64>) {
121        let mut buf: &[u8] = &mut bytes;
122        assert_eq!(buf.try_get_u64_le(), expected);
123    }
124
125    #[rstest]
126    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 0u8], Ok(0x0102030405060708090a0b0c0d0e0f00))]
127    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8], Err(VarIntError::BufferUnderflow))]
128    #[case(vec![], Err(VarIntError::BufferUnderflow))]
129    fn test_u128(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u128>) {
130        let mut buf: &[u8] = &mut bytes;
131        assert_eq!(buf.try_get_u128(), expected);
132    }
133    #[rstest]
134    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 0u8], Ok(0x000f0e0d0c0b0a090807060504030201))]
135    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8], Err(VarIntError::BufferUnderflow))]
136    #[case(vec![], Err(VarIntError::BufferUnderflow))]
137    fn test_u128_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<u128>) {
138        let mut buf: &[u8] = &mut bytes;
139        assert_eq!(buf.try_get_u128_le(), expected);
140    }
141
142    #[rstest]
143    #[case(vec![1u8], Ok(1))]
144    #[case(vec![], Err(VarIntError::BufferUnderflow))]
145    fn test_i8(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i8>) {
146        let mut buf: &[u8] = &mut bytes;
147        assert_eq!(buf.try_get_i8(), expected);
148    }
149
150    #[rstest]
151    #[case(vec![1u8, 2u8], Ok(0x0102))]
152    #[case(vec![1u8], Err(VarIntError::BufferUnderflow))]
153    #[case(vec![], Err(VarIntError::BufferUnderflow))]
154    fn test_i16(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i16>) {
155        let mut buf: &[u8] = &mut bytes;
156        assert_eq!(buf.try_get_i16(), expected);
157    }
158    #[rstest]
159    #[case(vec![1u8, 2u8], Ok(0x0201))]
160    #[case(vec![1u8], Err(VarIntError::BufferUnderflow))]
161    #[case(vec![], Err(VarIntError::BufferUnderflow))]
162    fn test_i16_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i16>) {
163        let mut buf: &[u8] = &mut bytes;
164        assert_eq!(buf.try_get_i16_le(), expected);
165    }
166
167    #[rstest]
168    #[case(vec![1u8, 2u8, 3u8, 4u8], Ok(0x01020304))]
169    #[case(vec![1u8, 2u8, 3u8], Err(VarIntError::BufferUnderflow))]
170    #[case(vec![], Err(VarIntError::BufferUnderflow))]
171    fn test_i32(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i32>) {
172        let mut buf: &[u8] = &mut bytes;
173        assert_eq!(buf.try_get_i32(), expected);
174    }
175    #[rstest]
176    #[case(vec![1u8, 2u8, 3u8, 4u8], Ok(0x04030201))]
177    #[case(vec![1u8, 2u8, 3u8], Err(VarIntError::BufferUnderflow))]
178    #[case(vec![], Err(VarIntError::BufferUnderflow))]
179    fn test_i32_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i32>) {
180        let mut buf: &[u8] = &mut bytes;
181        assert_eq!(buf.try_get_i32_le(), expected);
182    }
183
184    #[rstest]
185    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8], Ok(0x0102030405060708))]
186    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8], Err(VarIntError::BufferUnderflow))]
187    #[case(vec![], Err(VarIntError::BufferUnderflow))]
188    fn test_i64(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i64>) {
189        let mut buf: &[u8] = &mut bytes;
190        assert_eq!(buf.try_get_i64(), expected);
191    }
192    #[rstest]
193    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8], Ok(0x0807060504030201))]
194    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8], Err(VarIntError::BufferUnderflow))]
195    #[case(vec![], Err(VarIntError::BufferUnderflow))]
196    fn test_i64_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i64>) {
197        let mut buf: &[u8] = &mut bytes;
198        assert_eq!(buf.try_get_i64_le(), expected);
199    }
200
201    #[rstest]
202    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 0u8], Ok(0x0102030405060708090a0b0c0d0e0f00))]
203    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8], Err(VarIntError::BufferUnderflow))]
204    #[case(vec![], Err(VarIntError::BufferUnderflow))]
205    fn test_i128(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i128>) {
206        let mut buf: &[u8] = &mut bytes;
207        assert_eq!(buf.try_get_i128(), expected);
208    }
209    #[rstest]
210    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 0u8], Ok(0x000f0e0d0c0b0a090807060504030201))]
211    #[case(vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8], Err(VarIntError::BufferUnderflow))]
212    #[case(vec![], Err(VarIntError::BufferUnderflow))]
213    fn test_i128_le(#[case] mut bytes: Vec<u8>, #[case] expected: VarIntResult<i128>) {
214        let mut buf: &[u8] = &mut bytes;
215        assert_eq!(buf.try_get_i128_le(), expected);
216    }
217}