falco_event/types/
bytebuf.rs1use crate::fields::{FromBytes, FromBytesError, ToBytes};
2use std::fmt::{Debug, Formatter, Write as _};
3use std::io::Write;
4
5impl<'a> FromBytes<'a> for &'a [u8] {
6 #[inline]
7 fn from_bytes(buf: &mut &'a [u8]) -> Result<Self, FromBytesError> {
8 Ok(std::mem::take(buf))
9 }
10}
11
12impl ToBytes for &[u8] {
13 #[inline]
14 fn binary_size(&self) -> usize {
15 self.len()
16 }
17
18 #[inline]
19 fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
20 writer.write_all(self)
21 }
22
23 #[inline]
24 fn default_repr() -> impl ToBytes {
25 &[] as &[u8]
26 }
27}
28
29pub struct ByteBufFormatter<'a>(pub &'a [u8]);
36
37impl Debug for ByteBufFormatter<'_> {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 #[allow(deprecated)]
41 if f.flags() & 16 != 0 {
42 let mut first = true;
43 for c in self.0 {
44 if first {
45 first = false;
46 } else {
47 write!(f, " ")?;
48 }
49 write!(f, "{:02x}", *c)?;
50 }
51 } else {
52 for c in self.0 {
53 let c = *c;
54 if !(b' '..=0x7e).contains(&c) {
55 f.write_char('.')?;
56 } else {
57 f.write_char(c as char)?;
58 }
59 }
60 }
61
62 Ok(())
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::fields::{FromBytes, ToBytes};
69
70 #[test]
71 fn test_bytebuf() {
72 let data = b"foo".as_slice();
73 let mut binary = Vec::new();
74
75 data.write(&mut binary).unwrap();
76 hexdump::hexdump(binary.as_slice());
77
78 assert_eq!(binary.as_slice(), "foo".as_bytes());
79
80 let mut buf = binary.as_slice();
81 let loaded = <&[u8]>::from_bytes(&mut buf).unwrap();
82 assert_eq!(loaded, "foo".as_bytes());
83 }
84
85 #[test]
86 fn test_bytebuf_inner_nul() {
87 let data = b"f\0oo".as_slice();
88 let mut binary = Vec::new();
89
90 data.write(&mut binary).unwrap();
91 hexdump::hexdump(binary.as_slice());
92
93 assert_eq!(binary.as_slice(), "f\0oo".as_bytes());
94
95 let mut buf = binary.as_slice();
96 let loaded = <&[u8]>::from_bytes(&mut buf).unwrap();
97 assert_eq!(loaded, "f\0oo".as_bytes());
98 }
99}