Skip to main content

libtw2_buffer/
traits.rs

1use crate::with_buffer;
2use crate::Buffer;
3use crate::BufferRef;
4use std::fs;
5use std::io;
6use std::io::Read;
7use std::net;
8use std::process;
9
10/// A utility function for unsafely implementing `ReadBufferRef` for readers
11/// that don't read the buffer passed to `Read::read`.
12pub unsafe fn read_buffer_ref<'d, 's, T: Read>(
13    reader: &mut T,
14    mut buf: BufferRef<'d, 's>,
15) -> io::Result<&'d [u8]> {
16    let read = reader.read(buf.uninitialized_mut())?;
17    buf.advance(read);
18    Ok(buf.initialized())
19}
20
21/// An internal trait to be implemented by `T: Read` which do not access the
22/// read buffer in `Read::read`.
23pub unsafe trait ReadBufferMarker: Read {}
24
25/// An internal trait to be implemented by `T: Read` which do not access the
26/// read buffer in `Read::read`. Prefer implementing `ReadBufferMarker` over
27/// this.
28pub trait ReadBufferRef: Read {
29    /// Reads (equivalently to `Read::read`) into the buffer ref and returns
30    /// the newly written bytes.
31    fn read_buffer_ref<'d, 's>(&mut self, buf: BufferRef<'d, 's>) -> io::Result<&'d [u8]>;
32}
33
34/// Trait to read to `T: Buffer`.
35///
36/// This trait should be imported to read into buffers.
37pub trait ReadBuffer: ReadBufferRef {
38    /// Reads (equivalently to `Read::read`) into the buffer and returns the
39    /// newly read bytes.
40    fn read_buffer<'d, B: Buffer<'d>>(&mut self, buf: B) -> io::Result<&'d [u8]> {
41        with_buffer(buf, |buf| self.read_buffer_ref(buf))
42    }
43}
44
45impl<T: ReadBufferRef> ReadBuffer for T {}
46impl<T: ReadBufferMarker> ReadBufferRef for T {
47    fn read_buffer_ref<'d, 's>(&mut self, buf: BufferRef<'d, 's>) -> io::Result<&'d [u8]> {
48        unsafe { read_buffer_ref(self, buf) }
49    }
50}
51
52unsafe impl ReadBufferMarker for fs::File {}
53unsafe impl ReadBufferMarker for io::Empty {}
54unsafe impl ReadBufferMarker for io::Repeat {}
55unsafe impl ReadBufferMarker for io::Stdin {}
56unsafe impl ReadBufferMarker for net::TcpStream {}
57unsafe impl ReadBufferMarker for process::ChildStderr {}
58unsafe impl ReadBufferMarker for process::ChildStdout {}
59unsafe impl<'a> ReadBufferMarker for &'a [u8] {}
60unsafe impl<'a> ReadBufferMarker for &'a fs::File {}
61unsafe impl<'a> ReadBufferMarker for &'a net::TcpStream {}
62unsafe impl<'a> ReadBufferMarker for io::StdinLock<'a> {}
63unsafe impl<R> ReadBufferMarker for io::Take<R> where R: ReadBufferMarker {}
64unsafe impl<R> ReadBufferMarker for io::BufReader<R> where R: ReadBufferMarker {}
65unsafe impl<T, U> ReadBufferMarker for io::Chain<T, U>
66where
67    T: ReadBufferMarker,
68    U: ReadBufferMarker,
69{
70}
71
72unsafe impl<'a, R> ReadBufferMarker for &'a mut R where R: ReadBufferMarker {}
73unsafe impl<R> ReadBufferMarker for Box<R> where R: ReadBufferMarker {}