fraiseql_wire/util/bytes/
mod.rs1use bytes::{Buf, Bytes};
4use std::io;
5
6pub trait BytesExt {
8 fn read_cstr(&mut self) -> io::Result<String>;
15
16 fn read_i32_be(&mut self) -> io::Result<i32>;
22
23 fn read_i16_be(&mut self) -> io::Result<i16>;
29}
30
31impl BytesExt for Bytes {
32 fn read_cstr(&mut self) -> io::Result<String> {
33 let null_pos = self
34 .iter()
35 .position(|&b| b == 0)
36 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "no null terminator"))?;
37
38 let s = String::from_utf8(self.slice(..null_pos).to_vec())
39 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
40
41 self.advance(null_pos + 1);
42 Ok(s)
43 }
44
45 fn read_i32_be(&mut self) -> io::Result<i32> {
46 if self.remaining() < 4 {
47 return Err(io::Error::new(
48 io::ErrorKind::UnexpectedEof,
49 "not enough bytes",
50 ));
51 }
52 Ok(self.get_i32())
53 }
54
55 fn read_i16_be(&mut self) -> io::Result<i16> {
56 if self.remaining() < 2 {
57 return Err(io::Error::new(
58 io::ErrorKind::UnexpectedEof,
59 "not enough bytes",
60 ));
61 }
62 Ok(self.get_i16())
63 }
64}
65
66#[cfg(test)]
67mod tests;