miltr_utils/
lib.rs

1#![doc = include_str!("../Readme.md")]
2
3use std::mem::size_of;
4
5use bytes::{Buf, BytesMut};
6
7/// Safe extensions to methods from [`bytes::BytesMut`].
8pub trait ByteParsing {
9    /// Split at the given delimiter.
10    ///
11    /// Return the split off bytes without the delimiter
12    fn delimited(&mut self, delimiter: u8) -> Option<BytesMut>;
13
14    /// Bounds checked variant of [`bytes::BytesMut::split_to`]
15    fn safe_split_to(&mut self, at: usize) -> Option<BytesMut>;
16
17    /// Bounds checked variant of [`bytes::BytesMut::split_off`]
18    fn safe_split_off(&mut self, at: usize) -> Option<BytesMut>;
19
20    /// Bounds checked variant of [`bytes::BytesMut::get_u8`]
21    fn safe_get_u8(&mut self) -> Option<u8>;
22
23    /// Bounds checked variant of [`bytes::BytesMut::get_u32`]
24    fn safe_get_u32(&mut self) -> Option<u32>;
25}
26
27impl ByteParsing for BytesMut {
28    fn delimited(&mut self, delimiter: u8) -> Option<BytesMut> {
29        let index = self.iter().position(|&b| b == delimiter)?;
30
31        let off = self.split_to(index);
32        self.advance(1);
33
34        Some(off)
35    }
36
37    fn safe_split_to(&mut self, at: usize) -> Option<Self> {
38        if at > self.len() {
39            return None;
40        }
41        Some(self.split_to(at))
42    }
43
44    fn safe_split_off(&mut self, at: usize) -> Option<Self> {
45        if at > self.capacity() {
46            return None;
47        }
48        Some(self.split_off(at))
49    }
50
51    fn safe_get_u8(&mut self) -> Option<u8> {
52        if self.is_empty() {
53            return None;
54        }
55        Some(self.get_u8())
56    }
57
58    fn safe_get_u32(&mut self) -> Option<u32> {
59        if self.len() < size_of::<u32>() {
60            return None;
61        }
62        Some(self.get_u32())
63    }
64}
65
66#[macro_export]
67macro_rules! debug {
68    ($($arg:tt)+) => {
69        #[cfg(feature = "tracing")]
70        {
71            tracing::debug!($($arg)+);
72        }
73    }
74}
75
76#[macro_export]
77macro_rules! trace {
78    ($($arg:tt)+) => {
79        #[cfg(feature = "tracing")]
80        {
81            tracing::trace!($($arg)+);
82        }
83    }
84}