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 value of type `T` from a buffer that is exactly the length of `T`."
69 ""
70 "Returns an error if any data remains.";
71 #[inline]
72 pub fn decode_exact<T: $value<'a>>(self) -> Result<T, DecoderError> {
73 let (value, remaining) = T::$value_call(self)?;
74 if !remaining.is_empty() {
75 Err(DecoderError::UnexpectedBytes(remaining.len()))
76 } else {
77 Ok(value)
78 }
79 }
80 }
81
82 doc_comment! {
83 "Decode a slice prefixed by type `Length`, splitting the data from the"
84 "current buffer."
85
86 "With a `Length` as encoded `u8`:"
87 "```rust"
88 "# use s2n_codec::*;"
89 "let mut data = [5, 0, 1, 2, 3, 4];"
90 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
91 "let (slice, buffer) = buffer.decode_slice_with_len_prefix::<u8>().unwrap();"
92 "assert_eq!(slice, [0u8, 1, 2, 3, 4][..]);"
93 "assert!(buffer.is_empty())"
94 "```"
95
96 "With a `Length` as encoded `u16`:"
97 "```rust"
98 "# use s2n_codec::*;"
99 "let mut data = [0, 5, 0, 1, 2, 3, 4];"
100 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
101 "let (slice, buffer) = buffer.decode_slice_with_len_prefix::<u16>().unwrap();"
102 "assert_eq!(slice, [0u8, 1, 2, 3, 4][..]);"
103 "assert!(buffer.is_empty())"
104 "```";
105
106 #[inline]
107 pub fn decode_slice_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>>(
108 self,
109 ) -> $result<'a, Self> {
110 let (len, buffer) = self.decode::<Length>()?;
111 let len = len.try_into().map_err(|_| DecoderError::LengthCapacityExceeded)?;
112 buffer.decode_slice(len)
113 }
114 }
115
116 doc_comment! {
117 "Decode a value of type `T` prefixed by type `Length`, splitting the data from the"
118 "current buffer."
119
120 "With a `Length` as encoded `u8` and `T` as `u16`:"
121 "```rust"
122 "# use s2n_codec::*;"
123 "let mut data = [2, 0, 1, 2, 3];"
124 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
125 "let (value, buffer) = buffer.decode_with_len_prefix::<u8, u16>().unwrap();"
126 "assert_eq!(value, 1);"
127 "assert_eq!(buffer, [2, 3][..])"
128 "```"
129
130 concat!("The `", stringify!($value) ,"` implementation of `T` must consume the entire subslice")
131 "otherwise an error will be returned."
132
133 "```rust"
134 "# use s2n_codec::*;"
135 "let mut data = [3, 0, 1, 2];"
136 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
137 "let result = buffer.decode_with_len_prefix::<u8, u16>();"
138 "assert!(result.is_err())"
139 "```";
140
141 #[inline]
142 pub fn decode_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>, T: $value<'a>>(
143 self,
144 ) -> $result<'a, T> {
145 let (slice, buffer) = self.decode_slice_with_len_prefix::<Length>()?;
146 let (value, slice) = slice.decode::<T>()?;
147 slice.ensure_empty()?;
148 Ok((value, buffer))
149 }
150 }
151
152 doc_comment! {
153 "Decode a parameterized value of type `T` implementing `"
154 stringify!($parameterized) "`";
155
156 #[inline]
157 pub fn decode_parameterized<T: $parameterized<'a>>(
158 self,
159 parameter: T::Parameter,
160 ) -> $result<'a, T> {
161 T::$parameterized_call(parameter, self)
162 }
163 }
164
165 doc_comment! {
166 "Skip a `count` of bytes, discarding the bytes"
167
168 "```rust"
169 "# use s2n_codec::*;"
170 "let mut data = [0, 1, 2, 3, 4];"
171 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
172 "let buffer = buffer.skip(3).unwrap();"
173 "assert_eq!(buffer, [3, 4][..]);"
174 "```";
175
176 #[inline]
177 pub fn skip(self, count: usize) -> Result<$name<'a>, DecoderError> {
178 self.decode_slice(count).map(|(_, buffer)| buffer)
179 }
180 }
181
182 doc_comment! {
183 "Skip a number of bytes encoded as a length prefix of type `Length`"
184
185 "With a `Length` encoded as `u8`:"
186 "```rust"
187 "# use s2n_codec::*;"
188 "let mut data = [5, 0, 1, 2, 3, 4];"
189 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
190 "let buffer = buffer.skip_with_len_prefix::<u8>().unwrap();"
191 "assert!(buffer.is_empty());"
192 "```";
193
194 #[inline]
195 pub fn skip_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>>(
196 self,
197 ) -> Result<$name<'a>, DecoderError> {
198 let (len, buffer) = self.decode::<Length>()?;
199 let len = len.try_into().map_err(|_| DecoderError::LengthCapacityExceeded)?;
200 buffer.skip(len)
201 }
202 }
203
204 doc_comment! {
205 "Skip a `count` of bytes, returning a `CheckedRange` for later access";
206 #[inline]
209 pub fn skip_into_range(
210 self,
211 count: usize,
212 original_buffer: &crate::DecoderBufferMut,
213 ) -> $result<'a, crate::CheckedRange> {
214 let start = original_buffer.len() - self.len();
215 let (slice, buffer) = self.decode_slice(count)?;
216 let end = start + count;
217 Ok((
218 crate::CheckedRange::new(start, end, slice.bytes.as_ptr()),
219 buffer,
220 ))
221 }
222 }
223
224 doc_comment! {
225 "Skip a number of bytes encoded as a length prefix of type `Length`"
226 "into a `CheckedRange` for later access";
227 #[inline]
230 pub fn skip_into_range_with_len_prefix<Length: $value<'a> + core::convert::TryInto<usize>>(
231 self,
232 original_buffer: &crate::DecoderBufferMut,
233 ) -> $result<'a, crate::CheckedRange> {
234 let (len, buffer) = self.decode::<Length>()?;
235 let len = len.try_into().map_err(|_| DecoderError::LengthCapacityExceeded)?;
236 buffer.skip_into_range(len, original_buffer)
237 }
238 }
239
240 doc_comment! {
241 "Reads data from a `CheckedRange`";
242 #[inline]
245 pub fn get_checked_range(&self, range: &crate::CheckedRange) -> DecoderBuffer<'_> {
246 range.get(self.bytes).into()
247 }
248 }
249
250 doc_comment! {
251 "Create a peeking `DecoderBuffer` from the current buffer view"
252
253 "```rust"
254 "# use s2n_codec::*;"
255 "let mut data = [0, 1];"
256 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
257 ""
258 "let peek = buffer.peek();"
259 "let (value, peek) = peek.decode::<u16>().unwrap();"
260 "assert_eq!(value, 1);"
261 "assert!(peek.is_empty());"
262 ""
263 "// `buffer` still contains the previous view"
264 "assert_eq!(buffer, [0, 1][..]);"
265 "```";
266
267 #[inline]
268 #[must_use]
269 pub fn peek(&'a self) -> crate::DecoderBuffer<'a> {
270 crate::DecoderBuffer::new(self.bytes)
271 }
272 }
273
274 doc_comment! {
275 "Returns a single byte at `index`"
276
277 "```rust"
278 "# use s2n_codec::*;"
279 "let mut data = [0, 1, 2];"
280 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
281 ""
282 "assert_eq!(buffer.peek_byte(0).unwrap(), 0);"
283 "assert_eq!(buffer.peek_byte(1).unwrap(), 1);"
284 "assert_eq!(buffer.peek_byte(2).unwrap(), 2);"
285 ""
286 "// `buffer` has not changed"
287 "assert_eq!(buffer, [0, 1, 2][..]);"
288 "```";
289
290 #[inline]
291 pub fn peek_byte(&self, index: usize) -> Result<u8, DecoderError> {
292 self.bytes
293 .get(index)
294 .cloned()
295 .ok_or_else(|| DecoderError::UnexpectedEof(index))
296 }
297 }
298
299 #[inline]
301 pub fn peek_range(
302 &self,
303 range: core::ops::Range<usize>,
304 ) -> Result<crate::DecoderBuffer<'_>, DecoderError> {
305 let end = range.end;
306 self.bytes
307 .get(range)
308 .map(|bytes| bytes.into())
309 .ok_or_else(|| DecoderError::UnexpectedEof(end))
310 }
311
312 doc_comment! {
313 "Returns an error if the buffer is not empty."
314
315 "```rust"
316 "# use s2n_codec::*;"
317 "let mut data = [1];"
318 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
319 ""
320 "assert!(buffer.ensure_empty().is_err());"
321 "let (_, buffer) = buffer.decode::<u8>().unwrap();"
322 "assert!(buffer.ensure_empty().is_ok());"
323 "```";
324
325 #[inline]
326 pub fn ensure_empty(&self) -> Result<(), DecoderError> {
327 if !self.is_empty() {
328 Err(DecoderError::UnexpectedBytes(self.len()))
329 } else {
330 Ok(())
331 }
332 }
333 }
334
335 doc_comment! {
336 "Returns an error if the buffer does not have at least `len` bytes."
337
338 "```rust"
339 "# use s2n_codec::*;"
340 "let mut data = [0, 1, 2];"
341 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
342 ""
343 "assert!(buffer.ensure_len(2).is_ok());"
344 "assert!(buffer.ensure_len(5).is_err());"
345 "```";
346
347 #[inline]
348 pub fn ensure_len(&self, len: usize) -> Result<(), DecoderError> {
349 if self.len() < len {
350 Err(DecoderError::UnexpectedEof(len))
351 } else {
352 Ok(())
353 }
354 }
355 }
356
357 doc_comment! {
358 "Returns the number of bytes in the buffer."
359
360 "```rust"
361 "# use s2n_codec::*;"
362 "let mut data = [0, 1, 2];"
363 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
364 ""
365 "assert_eq!(buffer.len(), 3);"
366 "let (_, buffer) = buffer.decode::<u8>().unwrap();"
367 "assert_eq!(buffer.len(), 2);"
368 "```";
369
370 #[inline]
371 pub fn len(&self) -> usize {
372 self.bytes.len()
373 }
374 }
375
376 doc_comment! {
377 "Returns true if the buffer has a length of 0."
378
379 "```rust"
380 "# use s2n_codec::*;"
381 "let mut data = [1];"
382 concat!("let buffer = ", stringify!($name), "::new(&mut data);")
383 ""
384 "assert!(!buffer.is_empty());"
385 "let (_, buffer) = buffer.decode::<u8>().unwrap();"
386 "assert!(buffer.is_empty());"
387 "```";
388
389 #[inline]
390 pub fn is_empty(&self) -> bool {
391 self.bytes.is_empty()
392 }
393 }
394
395 #[inline]
398 pub fn as_less_safe_slice(&'a self) -> &'a [u8] {
399 self.bytes
400 }
401 }
402
403 impl<'a> From<&'a mut [u8]> for $name<'a> {
404 #[inline]
405 fn from(bytes: &'a mut [u8]) -> Self {
406 Self::new(bytes)
407 }
408 }
409
410 impl<'a> PartialEq<[u8]> for $name<'a> {
411 #[inline]
412 fn eq(&self, rhs: &[u8]) -> bool {
413 let bytes: &[u8] = self.bytes.as_ref();
414 bytes.eq(rhs)
415 }
416 }
417 };
418}
419
420pub mod buffer;
421pub mod buffer_mut;
422pub mod checked_range;
423#[macro_use]
424pub mod value;
425
426pub use buffer::*;
427pub use buffer_mut::*;
428pub use checked_range::*;
429pub use value::*;
430
431#[derive(Clone, Copy, Debug)]
432pub enum DecoderError {
433 UnexpectedEof(usize),
434 UnexpectedBytes(usize),
435 LengthCapacityExceeded,
436 InvariantViolation(&'static str), }
438
439impl core::error::Error for DecoderError {}
440
441use core::fmt;
442impl fmt::Display for DecoderError {
443 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
444 if cfg!(kani) {
446 return Ok(());
447 }
448
449 match self {
450 Self::UnexpectedEof(len) => write!(f, "unexpected eof: {len}"),
451 Self::UnexpectedBytes(len) => write!(f, "unexpected bytes: {len}"),
452 Self::LengthCapacityExceeded => write!(
453 f,
454 "length could not be represented in platform's usize type"
455 ),
456 Self::InvariantViolation(msg) => write!(f, "{msg}"),
457 }
458 }
459}
460
461impl From<DecoderError> for &'static str {
462 fn from(error: DecoderError) -> Self {
463 match error {
464 DecoderError::UnexpectedEof(_len) => "unexpected eof",
465 DecoderError::UnexpectedBytes(_len) => "unexpected bytes",
466 DecoderError::LengthCapacityExceeded => {
467 "length could not be represented in platform's usize type"
468 }
469 DecoderError::InvariantViolation(msg) => msg,
470 }
471 }
472}
473
474#[macro_export]
475macro_rules! decoder_invariant {
476 ($expr:expr, $invariant:expr) => {
477 if !($expr) {
478 return ::core::result::Result::Err(
479 $crate::decoder::DecoderError::InvariantViolation($invariant).into(),
480 );
481 }
482 };
483}
484
485#[cfg(test)]
486mod tests {
487 use super::*;
488
489 #[test]
492 fn decode_exact_success() {
493 let buf = DecoderBuffer::new(&[0, 42]);
494 let val: u16 = buf.decode_exact().unwrap();
495 assert_eq!(val, 42);
496 }
497
498 #[test]
499 fn decode_exact_trailing_bytes_error() {
500 let buf = DecoderBuffer::new(&[1, 2, 3]);
501 assert!(buf.decode_exact::<u8>().is_err());
502 }
503
504 #[test]
505 fn decode_exact_too_short_error() {
506 let buf = DecoderBuffer::new(&[1]);
507 assert!(buf.decode_exact::<u32>().is_err());
508 }
509
510 #[test]
511 fn decode_exact_empty_buffer_error() {
512 let buf = DecoderBuffer::new(&[]);
513 assert!(buf.decode_exact::<u8>().is_err());
514 }
515
516 #[test]
519 fn decoder_error_implements_std_error() {
520 fn takes_error(_: &dyn std::error::Error) {}
521 let err = DecoderError::UnexpectedEof(0);
522 takes_error(&err);
523 }
524
525 #[test]
526 fn decoder_error_display() {
527 let err = DecoderError::UnexpectedEof(5);
528 assert_eq!(format!("{err}"), "unexpected eof: 5");
529
530 let err = DecoderError::UnexpectedBytes(3);
531 assert_eq!(format!("{err}"), "unexpected bytes: 3");
532
533 let err = DecoderError::InvariantViolation("bad");
534 assert_eq!(format!("{err}"), "bad");
535 }
536
537 #[test]
538 fn decoder_error_in_box_dyn() -> Result<(), Box<dyn std::error::Error>> {
539 let buf = DecoderBuffer::new(&[0, 1]);
540 let _: u16 = buf.decode_exact()?;
541 Ok(())
542 }
543}