1 //! An internal module used for testing cradle.
2 
3 use std::io::{self, Write};
4 
5 #[derive(Clone, Debug)]
6 pub(crate) struct Stdout;
7 
8 impl Write for Stdout {
write(&mut self, buf: &[u8]) -> io::Result<usize>9     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
10         io::stdout().write(buf)
11     }
12 
flush(&mut self) -> io::Result<()>13     fn flush(&mut self) -> io::Result<()> {
14         io::stdout().flush()
15     }
16 }
17 
18 #[derive(Clone, Debug)]
19 pub(crate) struct Stderr;
20 
21 impl Write for Stderr {
write(&mut self, buf: &[u8]) -> io::Result<usize>22     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
23         io::stderr().write(buf)
24     }
25 
flush(&mut self) -> io::Result<()>26     fn flush(&mut self) -> io::Result<()> {
27         io::stderr().flush()
28     }
29 }
30 
31 #[doc(hidden)]
32 #[derive(Clone, Debug)]
33 pub(crate) struct Context<Stdout, Stderr> {
34     pub(crate) stdout: Stdout,
35     pub(crate) stderr: Stderr,
36 }
37 
38 impl Context<Stdout, Stderr> {
production() -> Self39     pub(crate) fn production() -> Self {
40         Context {
41             stdout: Stdout,
42             stderr: Stderr,
43         }
44     }
45 }
46 
47 #[cfg(test)]
48 mod test {
49     use super::*;
50     use std::{
51         io::Cursor,
52         sync::{Arc, Mutex},
53     };
54 
55     #[derive(Clone, Debug)]
56     pub(crate) struct TestOutput(Arc<Mutex<Cursor<Vec<u8>>>>);
57 
58     impl TestOutput {
new() -> TestOutput59         fn new() -> TestOutput {
60             TestOutput(Arc::new(Mutex::new(Cursor::new(Vec::new()))))
61         }
62     }
63 
64     impl Write for TestOutput {
write(&mut self, buf: &[u8]) -> io::Result<usize>65         fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
66             let mut lock = self.0.lock().unwrap();
67             lock.write(buf)
68         }
69 
flush(&mut self) -> io::Result<()>70         fn flush(&mut self) -> io::Result<()> {
71             let mut lock = self.0.lock().unwrap();
72             lock.flush()
73         }
74     }
75 
76     impl Context<TestOutput, TestOutput> {
test() -> Self77         pub(crate) fn test() -> Self {
78             Context {
79                 stdout: TestOutput::new(),
80                 stderr: TestOutput::new(),
81             }
82         }
83 
stdout(&self) -> String84         pub(crate) fn stdout(&self) -> String {
85             let lock = self.stdout.0.lock().unwrap();
86             String::from_utf8(lock.clone().into_inner()).unwrap()
87         }
88 
stderr(&self) -> String89         pub(crate) fn stderr(&self) -> String {
90             let lock = self.stderr.0.lock().unwrap();
91             String::from_utf8(lock.clone().into_inner()).unwrap()
92         }
93     }
94 }
95