1#![doc = include_str!("../Readme.md")]
2
3use std::mem::size_of;
4
5use bytes::{Buf, BytesMut};
6
7pub trait ByteParsing {
9 fn delimited(&mut self, delimiter: u8) -> Option<BytesMut>;
13
14 fn safe_split_to(&mut self, at: usize) -> Option<BytesMut>;
16
17 fn safe_split_off(&mut self, at: usize) -> Option<BytesMut>;
19
20 fn safe_get_u8(&mut self) -> Option<u8>;
22
23 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}