tee/
lib.rs

1use std::io::{Read, Result, Write};
2
3/// An adapter for readers whose inputs
4/// are written to a tee(1)'d writer
5pub struct TeeReader<R: Read, W: Write> {
6    reader: R,
7    writer: W,
8}
9
10impl<R: Read, W: Write> TeeReader<R, W> {
11    /// Returns a TeeReader which can be used as Read whose
12    /// reads delegate ready bytes read to the provided reader and write to the provided
13    /// writer. This write must complete before the read completes.
14    ///
15    /// Errors reported by the read will be interpreted as Errors for the read
16    pub fn new(reader: R, writer: W) -> TeeReader<R, W> {
17        TeeReader {
18            reader: reader,
19            writer: writer,
20        }
21    }
22}
23
24impl<R: Read, W: Write> Read for TeeReader<R, W> {
25    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
26        let n = try!(self.reader.read(buf));
27        try!(self.writer.write_all(&buf[..n]));
28        Ok(n)
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use std::io::Read;
36
37    #[test]
38    fn tee() {
39        let mut reader = "It's over 9000!".as_bytes();
40        let mut teeout = Vec::new();
41        let mut stdout = Vec::new();
42        {
43            let mut tee = TeeReader::new(&mut reader, &mut teeout);
44            let _ = tee.read_to_end(&mut stdout);
45        }
46        assert_eq!(teeout, stdout);
47    }
48}