falco_event/types/string/
cstr.rs

1use crate::fields::{FromBytes, FromBytesError, ToBytes};
2use std::ffi::CStr;
3use std::io::Write;
4
5impl<'a> FromBytes<'a> for &'a CStr {
6    #[inline]
7    fn from_bytes(buf: &mut &'a [u8]) -> Result<Self, FromBytesError> {
8        let cstr = CStr::from_bytes_until_nul(buf).map_err(|_| FromBytesError::MissingNul)?;
9        let len = cstr.to_bytes().len();
10        *buf = &buf[len + 1..];
11        Ok(cstr)
12    }
13}
14
15impl ToBytes for &CStr {
16    #[inline]
17    fn binary_size(&self) -> usize {
18        self.to_bytes().len() + 1
19    }
20
21    #[inline]
22    fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
23        writer.write_all(self.to_bytes_with_nul())
24    }
25
26    #[inline]
27    fn default_repr() -> impl ToBytes {
28        0u8
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use crate::fields::{FromBytes, ToBytes};
35    use std::ffi::CStr;
36
37    #[test]
38    fn test_cstr() {
39        let s = CStr::from_bytes_until_nul(b"foo\0").unwrap();
40
41        let mut binary = Vec::new();
42        s.write(&mut binary).unwrap();
43
44        println!("{binary:02x?}");
45
46        assert_eq!(binary.as_slice(), b"foo\0".as_slice());
47
48        let mut buf = binary.as_slice();
49        let s2 = <&CStr>::from_bytes(&mut buf).unwrap();
50
51        assert_eq!(s2.to_bytes_with_nul(), b"foo\0".as_slice());
52        assert_eq!(buf.len(), 0);
53    }
54}