1macro_rules! doc_comment {
5 ($($x:expr)*; $($tt:tt)*) => {
6 doc_comment!(@doc concat!($($x, "\n",)*), $($tt)*);
7 };
8 (@doc $x:expr, $($tt:tt)*) => {
9 #[doc = $x]
10 $($tt)*
11 };
12}
13
14macro_rules! impl_buffer {
15 ($name:ident, $result:ident, $value:ident, $value_call:ident, $parameterized:ident, $parameterized_call:ident, $split:ident) => {
16 impl<'a> $name<'a> {
17 doc_comment! {
18 "Decode a slice of bytes by `count`, removing the slice from the current buffer"
19
20 "```"
21 "# use s2n_codec::*;"
22 "let mut data = [0, 1, 2, 3, 4];"
23 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
24 ""
25 "let (slice, buffer) = buffer.decode_slice(5).unwrap();"
26 "assert_eq!(slice, [0u8, 1, 2, 3, 4][..]);"
27 ""
28 "assert!(buffer.is_empty());"
29 "```";
30
31 #[inline]
32 pub fn decode_slice(self, count: usize) -> $result<'a, $name<'a>> {
33 self.ensure_len(count)?;
34
35 let (slice, remaining) = self.bytes.$split(count);
36
37 Ok((Self::new(slice), Self::new(remaining)))
38 }
39 }
40
41 doc_comment! {
42 "Decode a value of type `T`, splitting the data from the current buffer"
43
44 "```"
45 "# use s2n_codec::*;"
46 "let mut data = [0, 1, 2, 3, 4, 5, 6];"
47 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
48 ""
49 "let (value, buffer) = buffer.decode::<u8>().unwrap();"
50 "assert_eq!(value, 0);"
51 ""
52 "let (value, buffer) = buffer.decode::<u16>().unwrap();"
53 "assert_eq!(value, 258);"
54 ""
55 "let (value, buffer) = buffer.decode::<u32>().unwrap();"
56 "assert_eq!(value, 50_595_078);"
57 ""
58 "assert!(buffer.is_empty());"
59 "```";
60
61 #[inline]
62 pub fn decode<T: $value<'a>>(self) -> $result<'a, T> {
63 T::$value_call(self)
64 }
65 }
66
67 doc_comment! {
68 "Decode a slice prefixed by type `Length`, splitting the data from the"
69 "current buffer."
70
71 "With a `Length` as encoded `u8`:"
72 "```rust"
73 "# use s2n_codec::*;"
74 "let mut data = [5, 0, 1, 2, 3, 4];"
75 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
76 "let (slice, buffer) = buffer.decode_slice_with_len_prefix::<u8>().unwrap();"
77 "assert_eq!(slice, [0u8, 1, 2, 3, 4][..]);"
78 "assert!(buffer.is_empty())"
79 "```"
80
81 "With a `Length` as encoded `u16`:"
82 "```rust"
83 "# use s2n_codec::*;"
84 "let mut data = [0, 5, 0, 1, 2, 3, 4];"
85 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
86 "let (slice, buffer) = buffer.decode_slice_with_len_prefix::<u16>().unwrap();"
87 "assert_eq!(slice, [0u8, 1, 2, 3, 4][..]);"
88 "assert!(buffer.is_empty())"
89 "```";
90
91 #[inline]
92 pub fn decode_slice_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>>(
93 self,
94 ) -> $result<'a, Self> {
95 let (len, buffer) = self.decode::<Length>()?;
96 let len = len.try_into().map_err(|_| DecoderError::LengthCapacityExceeded)?;
97 buffer.decode_slice(len)
98 }
99 }
100
101 doc_comment! {
102 "Decode a value of type `T` prefixed by type `Length`, splitting the data from the"
103 "current buffer."
104
105 "With a `Length` as encoded `u8` and `T` as `u16`:"
106 "```rust"
107 "# use s2n_codec::*;"
108 "let mut data = [2, 0, 1, 2, 3];"
109 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
110 "let (value, buffer) = buffer.decode_with_len_prefix::<u8, u16>().unwrap();"
111 "assert_eq!(value, 1);"
112 "assert_eq!(buffer, [2, 3][..])"
113 "```"
114
115 concat!("The `", stringify!($value) ,"` implementation of `T` must consume the entire subslice")
116 "otherwise an error will be returned."
117
118 "```rust"
119 "# use s2n_codec::*;"
120 "let mut data = [3, 0, 1, 2];"
121 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
122 "let result = buffer.decode_with_len_prefix::<u8, u16>();"
123 "assert!(result.is_err())"
124 "```";
125
126 #[inline]
127 pub fn decode_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>, T: $value<'a>>(
128 self,
129 ) -> $result<'a, T> {
130 let (slice, buffer) = self.decode_slice_with_len_prefix::<Length>()?;
131 let (value, slice) = slice.decode::<T>()?;
132 slice.ensure_empty()?;
133 Ok((value, buffer))
134 }
135 }
136
137 doc_comment! {
138 "Decode a parameterized value of type `T` implementing `"
139 stringify!($parameterized) "`";
140
141 #[inline]
142 pub fn decode_parameterized<T: $parameterized<'a>>(
143 self,
144 parameter: T::Parameter,
145 ) -> $result<'a, T> {
146 T::$parameterized_call(parameter, self)
147 }
148 }
149
150 doc_comment! {
151 "Skip a `count` of bytes, discarding the bytes"
152
153 "```rust"
154 "# use s2n_codec::*;"
155 "let mut data = [0, 1, 2, 3, 4];"
156 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
157 "let buffer = buffer.skip(3).unwrap();"
158 "assert_eq!(buffer, [3, 4][..]);"
159 "```";
160
161 #[inline]
162 pub fn skip(self, count: usize) -> Result<$name<'a>, DecoderError> {
163 self.decode_slice(count).map(|(_, buffer)| buffer)
164 }
165 }
166
167 doc_comment! {
168 "Skip a number of bytes encoded as a length prefix of type `Length`"
169
170 "With a `Length` encoded as `u8`:"
171 "```rust"
172 "# use s2n_codec::*;"
173 "let mut data = [5, 0, 1, 2, 3, 4];"
174 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
175 "let buffer = buffer.skip_with_len_prefix::<u8>().unwrap();"
176 "assert!(buffer.is_empty());"
177 "```";
178
179 #[inline]
180 pub fn skip_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>>(
181 self,
182 ) -> Result<$name<'a>, DecoderError> {
183 let (len, buffer) = self.decode::<Length>()?;
184 let len = len.try_into().map_err(|_| DecoderError::LengthCapacityExceeded)?;
185 buffer.skip(len)
186 }
187 }
188
189 doc_comment! {
190 "Skip a `count` of bytes, returning a `CheckedRange` for later access";
191 #[inline]
194 pub fn skip_into_range(
195 self,
196 count: usize,
197 original_buffer: &crate::DecoderBufferMut,
198 ) -> $result<'a, crate::CheckedRange> {
199 let start = original_buffer.len() - self.len();
200 let (slice, buffer) = self.decode_slice(count)?;
201 let end = start + count;
202 Ok((
203 crate::CheckedRange::new(start, end, slice.bytes.as_ptr()),
204 buffer,
205 ))
206 }
207 }
208
209 doc_comment! {
210 "Skip a number of bytes encoded as a length prefix of type `Length`"
211 "into a `CheckedRange` for later access";
212 #[inline]
215 pub fn skip_into_range_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>>(
216 self,
217 original_buffer: &crate::DecoderBufferMut,
218 ) -> $result<'a, crate::CheckedRange> {
219 let (len, buffer) = self.decode::<Length>()?;
220 let len = len.try_into().map_err(|_| DecoderError::LengthCapacityExceeded)?;
221 buffer.skip_into_range(len, original_buffer)
222 }
223 }
224
225 doc_comment! {
226 "Reads data from a `CheckedRange`";
227 #[inline]
230 pub fn get_checked_range(&self, range: &crate::CheckedRange) -> DecoderBuffer<'_> {
231 range.get(self.bytes).into()
232 }
233 }
234
235 doc_comment! {
236 "Create a peeking `DecoderBuffer` from the current buffer view"
237
238 "```rust"
239 "# use s2n_codec::*;"
240 "let mut data = [0, 1];"
241 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
242 ""
243 "let peek = buffer.peek();"
244 "let (value, peek) = peek.decode::<u16>().unwrap();"
245 "assert_eq!(value, 1);"
246 "assert!(peek.is_empty());"
247 ""
248 "// `buffer` still contains the previous view"
249 "assert_eq!(buffer, [0, 1][..]);"
250 "```";
251
252 #[inline]
253 #[must_use]
254 pub fn peek(&'a self) -> crate::DecoderBuffer<'a> {
255 crate::DecoderBuffer::new(self.bytes)
256 }
257 }
258
259 doc_comment! {
260 "Returns a single byte at `index`"
261
262 "```rust"
263 "# use s2n_codec::*;"
264 "let mut data = [0, 1, 2];"
265 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
266 ""
267 "assert_eq!(buffer.peek_byte(0).unwrap(), 0);"
268 "assert_eq!(buffer.peek_byte(1).unwrap(), 1);"
269 "assert_eq!(buffer.peek_byte(2).unwrap(), 2);"
270 ""
271 "// `buffer` has not changed"
272 "assert_eq!(buffer, [0, 1, 2][..]);"
273 "```";
274
275 #[inline]
276 pub fn peek_byte(&self, index: usize) -> Result<u8, DecoderError> {
277 self.bytes
278 .get(index)
279 .cloned()
280 .ok_or_else(|| DecoderError::UnexpectedEof(index))
281 }
282 }
283
284 #[inline]
286 pub fn peek_range(
287 &self,
288 range: core::ops::Range<usize>,
289 ) -> Result<crate::DecoderBuffer<'_>, DecoderError> {
290 let end = range.end;
291 self.bytes
292 .get(range)
293 .map(|bytes| bytes.into())
294 .ok_or_else(|| DecoderError::UnexpectedEof(end))
295 }
296
297 doc_comment! {
298 "Returns an error if the buffer is not empty."
299
300 "```rust"
301 "# use s2n_codec::*;"
302 "let mut data = [1];"
303 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
304 ""
305 "assert!(buffer.ensure_empty().is_err());"
306 "let (_, buffer) = buffer.decode::<u8>().unwrap();"
307 "assert!(buffer.ensure_empty().is_ok());"
308 "```";
309
310 #[inline]
311 pub fn ensure_empty(&self) -> Result<(), DecoderError> {
312 if !self.is_empty() {
313 Err(DecoderError::UnexpectedBytes(self.len()))
314 } else {
315 Ok(())
316 }
317 }
318 }
319
320 doc_comment! {
321 "Returns an error if the buffer does not have at least `len` bytes."
322
323 "```rust"
324 "# use s2n_codec::*;"
325 "let mut data = [0, 1, 2];"
326 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
327 ""
328 "assert!(buffer.ensure_len(2).is_ok());"
329 "assert!(buffer.ensure_len(5).is_err());"
330 "```";
331
332 #[inline]
333 pub fn ensure_len(&self, len: usize) -> Result<(), DecoderError> {
334 if self.len() < len {
335 Err(DecoderError::UnexpectedEof(len))
336 } else {
337 Ok(())
338 }
339 }
340 }
341
342 doc_comment! {
343 "Returns the number of bytes in the buffer."
344
345 "```rust"
346 "# use s2n_codec::*;"
347 "let mut data = [0, 1, 2];"
348 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
349 ""
350 "assert_eq!(buffer.len(), 3);"
351 "let (_, buffer) = buffer.decode::<u8>().unwrap();"
352 "assert_eq!(buffer.len(), 2);"
353 "```";
354
355 #[inline]
356 pub fn len(&self) -> usize {
357 self.bytes.len()
358 }
359 }
360
361 doc_comment! {
362 "Returns true if the buffer has a length of 0."
363
364 "```rust"
365 "# use s2n_codec::*;"
366 "let mut data = [1];"
367 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
368 ""
369 "assert!(!buffer.is_empty());"
370 "let (_, buffer) = buffer.decode::<u8>().unwrap();"
371 "assert!(buffer.is_empty());"
372 "```";
373
374 #[inline]
375 pub fn is_empty(&self) -> bool {
376 self.bytes.is_empty()
377 }
378 }
379
380 #[inline]
383 pub fn as_less_safe_slice(&'a self) -> &'a [u8] {
384 self.bytes
385 }
386 }
387
388 impl<'a> From<&'a mut [u8]> for $name<'a> {
389 #[inline]
390 fn from(bytes: &'a mut [u8]) -> Self {
391 Self::new(bytes)
392 }
393 }
394
395 impl<'a> PartialEq<[u8]> for $name<'a> {
396 #[inline]
397 fn eq(&self, rhs: &[u8]) -> bool {
398 let bytes: &[u8] = self.bytes.as_ref();
399 bytes.eq(rhs)
400 }
401 }
402 };
403}
404
405pub mod buffer;
406pub mod buffer_mut;
407pub mod checked_range;
408#[macro_use]
409pub mod value;
410
411pub use buffer::*;
412pub use buffer_mut::*;
413pub use checked_range::*;
414pub use value::*;
415
416#[derive(Clone, Copy, Debug)]
417pub enum DecoderError {
418 UnexpectedEof(usize),
419 UnexpectedBytes(usize),
420 LengthCapacityExceeded,
421 InvariantViolation(&'static str), }
423
424use core::fmt;
425impl fmt::Display for DecoderError {
426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
427 if cfg!(kani) {
429 return Ok(());
430 }
431
432 match self {
433 Self::UnexpectedEof(len) => write!(f, "unexpected eof: {len}"),
434 Self::UnexpectedBytes(len) => write!(f, "unexpected bytes: {len}"),
435 Self::LengthCapacityExceeded => write!(
436 f,
437 "length could not be represented in platform's usize type"
438 ),
439 Self::InvariantViolation(msg) => write!(f, "{msg}"),
440 }
441 }
442}
443
444impl From<DecoderError> for &'static str {
445 fn from(error: DecoderError) -> Self {
446 match error {
447 DecoderError::UnexpectedEof(_len) => "unexpected eof",
448 DecoderError::UnexpectedBytes(_len) => "unexpected bytes",
449 DecoderError::LengthCapacityExceeded => {
450 "length could not be represented in platform's usize type"
451 }
452 DecoderError::InvariantViolation(msg) => msg,
453 }
454 }
455}
456
457#[macro_export]
458macro_rules! decoder_invariant {
459 ($expr:expr, $invariant:expr) => {
460 if !($expr) {
461 return ::core::result::Result::Err(
462 $crate::decoder::DecoderError::InvariantViolation($invariant).into(),
463 );
464 }
465 };
466}