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