1use std::io::{stderr, stdout, Write};
6
7use crate::TestBuffers;
8
9pub struct Writer {
12 stdout: Box<dyn Write>,
13 stderr: Box<dyn Write>,
14}
15
16impl Writer {
17 pub fn new_buffers<'a, O, E>(stdout: O, stderr: E) -> Self
20 where
21 O: Write + 'static,
22 E: Write + 'static,
23 {
24 let stdout = Box::new(stdout);
25 let stderr = Box::new(stderr);
26 Self { stdout, stderr }
27 }
28
29 pub fn new() -> Self {
31 Self::new_buffers(Box::new(stdout()), Box::new(stderr()))
32 }
33
34 pub fn new_test(test_writer: &TestBuffers) -> Self {
37 Self::new_buffers(test_writer.stdout.clone(), test_writer.stderr.clone())
38 }
39
40 pub fn stderr(&mut self) -> &'_ mut Box<dyn Write> {
41 &mut self.stderr
42 }
43}
44
45impl Write for Writer {
46 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
47 self.stdout.write(buf)
48 }
49
50 fn flush(&mut self) -> std::io::Result<()> {
51 self.stdout.flush()
52 }
53}
54
55#[cfg(test)]
56mod test {
57 use super::*;
58
59 #[test]
60 fn writer_implements_write() {
61 let test_buffers = TestBuffers::default();
62 let mut writer = Writer::new_test(&test_buffers);
63 writer.write_all(b"foobar").unwrap();
64
65 let (stdout, stderr) = test_buffers.into_strings();
66 assert_eq!(stdout, "foobar");
67 assert_eq!(stderr, "");
68 }
69
70 #[test]
71 fn writing_errors_goes_to_the_right_stream() {
72 let test_buffers = TestBuffers::default();
73 let mut writer = Writer::new_test(&test_buffers);
74 writeln!(writer.stderr(), "hello").unwrap();
75
76 let (stdout, stderr) = test_buffers.into_strings();
77 assert_eq!(stdout, "");
78 assert_eq!(stderr, "hello\n");
79 }
80}