tiny_http/util/
fused_reader.rs

1use std::io::{IoSliceMut, Read, Result as IoResult};
2
3/// Wraps another reader and provides "fused" behavior.
4/// When the underlying reader reaches EOF, it is dropped
5/// and the fused reader becomes an empty stub.
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct FusedReader<R: Read> {
8    inner: Option<R>,
9}
10
11impl<R: Read> FusedReader<R> {
12    pub fn new(inner: R) -> Self {
13        Self { inner: Some(inner) }
14    }
15
16    #[allow(dead_code)]
17    pub fn into_inner(self) -> Option<R> {
18        self.inner
19    }
20}
21
22impl<R: Read> Read for FusedReader<R> {
23    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
24        match &mut self.inner {
25            Some(r) => {
26                let l = r.read(buf)?;
27                if l == 0 {
28                    self.inner = None;
29                }
30                Ok(l)
31            }
32            None => Ok(0),
33        }
34    }
35
36    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
37        match &mut self.inner {
38            Some(r) => {
39                let l = r.read_vectored(bufs)?;
40                if l == 0 {
41                    self.inner = None;
42                }
43                Ok(l)
44            }
45            None => Ok(0),
46        }
47    }
48}