scuffle_bytes_util/
zero_copy.rs1use std::io;
4
5use crate::BytesCow;
6
7pub trait ZeroCopyReader<'a> {
9 fn try_read(&mut self, size: usize) -> Result<BytesCow<'a>, io::Error>;
14
15 fn as_std(&mut self) -> impl io::Read;
17}
18
19pub struct BytesBuf<B>(B);
21
22impl<B: bytes::Buf> From<B> for BytesBuf<B> {
23 fn from(buf: B) -> Self {
24 Self(buf)
25 }
26}
27
28impl<'a, B: bytes::Buf> ZeroCopyReader<'a> for BytesBuf<B> {
29 fn try_read(&mut self, size: usize) -> Result<BytesCow<'a>, io::Error> {
30 if self.0.remaining() < size {
31 return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Not enough data"));
32 }
33
34 Ok(BytesCow::from_bytes(self.0.copy_to_bytes(size)))
35 }
36
37 fn as_std(&mut self) -> impl io::Read {
38 bytes::Buf::reader(&mut self.0)
39 }
40}
41
42pub struct IoRead<R>(R);
48
49impl<R: io::Read> From<R> for IoRead<R> {
50 fn from(reader: R) -> Self {
51 Self(reader)
52 }
53}
54
55impl<'a, R: io::Read> ZeroCopyReader<'a> for IoRead<R> {
56 fn try_read(&mut self, size: usize) -> Result<BytesCow<'a>, io::Error> {
57 let mut buf = vec![0; size];
58 self.0.read_exact(&mut buf)?;
59 Ok(BytesCow::from_vec(buf))
60 }
61
62 fn as_std(&mut self) -> impl io::Read {
63 &mut self.0
64 }
65}
66
67pub struct Slice<'a>(io::Cursor<&'a [u8]>);
69
70impl<'a> From<&'a [u8]> for Slice<'a> {
71 fn from(slice: &'a [u8]) -> Self {
72 Self(io::Cursor::new(slice))
73 }
74}
75
76impl<'a> ZeroCopyReader<'a> for Slice<'a> {
77 fn try_read(&mut self, size: usize) -> Result<BytesCow<'a>, io::Error> {
78 let start = self.0.position() as usize;
79 let end = start + size;
80
81 if end > self.0.get_ref().len() {
82 return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Not enough data"));
83 }
84
85 let slice = &self.0.get_ref()[start..end];
86 self.0.set_position(end as u64);
87 Ok(BytesCow::from_slice(slice))
88 }
89
90 fn as_std(&mut self) -> impl io::Read {
91 &mut self.0
92 }
93}