|
1 | 1 | use std::io::{self, BufRead, Read, Result, Write};
|
2 |
| -#[cfg(feature = "test")] |
3 |
| -use std::{ |
4 |
| - io::Cursor, |
5 |
| - sync::{Arc, Mutex, MutexGuard}, |
6 |
| -}; |
7 | 2 |
|
8 | 3 | use enum_dispatch::enum_dispatch;
|
9 | 4 |
|
@@ -45,58 +40,6 @@ impl StdinSource for super::OSProcess {
|
45 | 40 | }
|
46 | 41 | }
|
47 | 42 |
|
48 |
| -// ----------------------- test support for stdin ------------------ |
49 |
| - |
50 |
| -#[cfg(feature = "test")] |
51 |
| -struct TestStdinLock<'a> { |
52 |
| - inner: MutexGuard<'a, Cursor<String>>, |
53 |
| -} |
54 |
| - |
55 |
| -#[cfg(feature = "test")] |
56 |
| -impl StdinLock for TestStdinLock<'_> {} |
57 |
| - |
58 |
| -#[cfg(feature = "test")] |
59 |
| -impl Read for TestStdinLock<'_> { |
60 |
| - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
61 |
| - self.inner.read(buf) |
62 |
| - } |
63 |
| -} |
64 |
| - |
65 |
| -#[cfg(feature = "test")] |
66 |
| -impl BufRead for TestStdinLock<'_> { |
67 |
| - fn fill_buf(&mut self) -> io::Result<&[u8]> { |
68 |
| - self.inner.fill_buf() |
69 |
| - } |
70 |
| - fn consume(&mut self, n: usize) { |
71 |
| - self.inner.consume(n) |
72 |
| - } |
73 |
| -} |
74 |
| - |
75 |
| -#[cfg(feature = "test")] |
76 |
| -pub(crate) type TestStdinInner = Arc<Mutex<Cursor<String>>>; |
77 |
| - |
78 |
| -#[cfg(feature = "test")] |
79 |
| -struct TestStdin(TestStdinInner); |
80 |
| - |
81 |
| -#[cfg(feature = "test")] |
82 |
| -impl Stdin for TestStdin { |
83 |
| - fn lock(&self) -> Box<dyn StdinLock + '_> { |
84 |
| - Box::new(TestStdinLock { |
85 |
| - inner: self.0.lock().unwrap_or_else(|e| e.into_inner()), |
86 |
| - }) |
87 |
| - } |
88 |
| - fn read_line(&self, buf: &mut String) -> Result<usize> { |
89 |
| - self.lock().read_line(buf) |
90 |
| - } |
91 |
| -} |
92 |
| - |
93 |
| -#[cfg(feature = "test")] |
94 |
| -impl StdinSource for super::TestProcess { |
95 |
| - fn stdin(&self) -> Box<dyn Stdin> { |
96 |
| - Box::new(TestStdin(self.stdin.clone())) |
97 |
| - } |
98 |
| -} |
99 |
| - |
100 | 43 | // -------------- stdout -------------------------------
|
101 | 44 |
|
102 | 45 | /// This is a stand-in for [`std::io::StdoutLock`] and [`std::io::StderrLock`].
|
@@ -187,81 +130,129 @@ impl StderrSource for super::OSProcess {
|
187 | 130 | }
|
188 | 131 | }
|
189 | 132 |
|
190 |
| -// ----------------------- test support for writers ------------------ |
191 |
| - |
192 | 133 | #[cfg(feature = "test")]
|
193 |
| -pub(super) struct TestWriterLock<'a> { |
194 |
| - inner: MutexGuard<'a, Vec<u8>>, |
195 |
| -} |
| 134 | +pub(crate) use self::test_support::*; |
196 | 135 |
|
197 | 136 | #[cfg(feature = "test")]
|
198 |
| -impl WriterLock for TestWriterLock<'_> {} |
| 137 | +mod test_support { |
| 138 | + use std::{ |
| 139 | + io::Cursor, |
| 140 | + sync::{Arc, Mutex, MutexGuard}, |
| 141 | + }; |
199 | 142 |
|
200 |
| -#[cfg(feature = "test")] |
201 |
| -impl Write for TestWriterLock<'_> { |
202 |
| - fn write(&mut self, buf: &[u8]) -> Result<usize> { |
203 |
| - self.inner.write(buf) |
| 143 | + use super::{super::TestProcess, *}; |
| 144 | + |
| 145 | + // ----------------------- test support for stdin ------------------ |
| 146 | + |
| 147 | + struct TestStdinLock<'a> { |
| 148 | + inner: MutexGuard<'a, Cursor<String>>, |
204 | 149 | }
|
205 | 150 |
|
206 |
| - fn flush(&mut self) -> Result<()> { |
207 |
| - Ok(()) |
| 151 | + impl StdinLock for TestStdinLock<'_> {} |
| 152 | + |
| 153 | + impl Read for TestStdinLock<'_> { |
| 154 | + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| 155 | + self.inner.read(buf) |
| 156 | + } |
208 | 157 | }
|
209 |
| -} |
210 | 158 |
|
211 |
| -#[cfg(feature = "test")] |
212 |
| -pub(super) type TestWriterInner = Arc<Mutex<Vec<u8>>>; |
213 |
| -/// A thread-safe test file handle that pretends to be e.g. stdout. |
214 |
| -#[derive(Clone, Default)] |
215 |
| -#[cfg(feature = "test")] |
216 |
| -pub(super) struct TestWriter(TestWriterInner); |
| 159 | + impl BufRead for TestStdinLock<'_> { |
| 160 | + fn fill_buf(&mut self) -> io::Result<&[u8]> { |
| 161 | + self.inner.fill_buf() |
| 162 | + } |
| 163 | + fn consume(&mut self, n: usize) { |
| 164 | + self.inner.consume(n) |
| 165 | + } |
| 166 | + } |
217 | 167 |
|
218 |
| -#[cfg(feature = "test")] |
219 |
| -impl TestWriter { |
220 |
| - pub(super) fn lock(&self) -> TestWriterLock<'_> { |
221 |
| - // The stream can be locked even if a test thread panicked: its state |
222 |
| - // will be ok |
223 |
| - TestWriterLock { |
224 |
| - inner: self.0.lock().unwrap_or_else(|e| e.into_inner()), |
| 168 | + pub(crate) type TestStdinInner = Arc<Mutex<Cursor<String>>>; |
| 169 | + |
| 170 | + struct TestStdin(TestStdinInner); |
| 171 | + |
| 172 | + impl Stdin for TestStdin { |
| 173 | + fn lock(&self) -> Box<dyn StdinLock + '_> { |
| 174 | + Box::new(TestStdinLock { |
| 175 | + inner: self.0.lock().unwrap_or_else(|e| e.into_inner()), |
| 176 | + }) |
| 177 | + } |
| 178 | + fn read_line(&self, buf: &mut String) -> Result<usize> { |
| 179 | + self.lock().read_line(buf) |
225 | 180 | }
|
226 | 181 | }
|
227 |
| -} |
228 | 182 |
|
229 |
| -#[cfg(feature = "test")] |
230 |
| -impl Writer for TestWriter { |
231 |
| - fn is_a_tty(&self) -> bool { |
232 |
| - false |
| 183 | + impl StdinSource for TestProcess { |
| 184 | + fn stdin(&self) -> Box<dyn Stdin> { |
| 185 | + Box::new(TestStdin(self.stdin.clone())) |
| 186 | + } |
233 | 187 | }
|
234 | 188 |
|
235 |
| - fn lock(&self) -> Box<dyn WriterLock + '_> { |
236 |
| - Box::new(self.lock()) |
| 189 | + // ----------------------- test support for writers ------------------ |
| 190 | + |
| 191 | + pub(in super::super) struct TestWriterLock<'a> { |
| 192 | + inner: MutexGuard<'a, Vec<u8>>, |
237 | 193 | }
|
238 | 194 |
|
239 |
| - fn terminal(&self) -> ColorableTerminal { |
240 |
| - ColorableTerminal::new(StreamSelector::TestWriter(self.clone())) |
| 195 | + impl WriterLock for TestWriterLock<'_> {} |
| 196 | + |
| 197 | + impl Write for TestWriterLock<'_> { |
| 198 | + fn write(&mut self, buf: &[u8]) -> Result<usize> { |
| 199 | + self.inner.write(buf) |
| 200 | + } |
| 201 | + |
| 202 | + fn flush(&mut self) -> Result<()> { |
| 203 | + Ok(()) |
| 204 | + } |
241 | 205 | }
|
242 |
| -} |
243 | 206 |
|
244 |
| -#[cfg(feature = "test")] |
245 |
| -impl Write for TestWriter { |
246 |
| - fn write(&mut self, buf: &[u8]) -> Result<usize> { |
247 |
| - self.lock().write(buf) |
| 207 | + pub(in super::super) type TestWriterInner = Arc<Mutex<Vec<u8>>>; |
| 208 | + |
| 209 | + /// A thread-safe test file handle that pretends to be e.g. stdout. |
| 210 | + #[derive(Clone, Default)] |
| 211 | + pub(in super::super) struct TestWriter(TestWriterInner); |
| 212 | + |
| 213 | + impl TestWriter { |
| 214 | + pub(in super::super) fn lock(&self) -> TestWriterLock<'_> { |
| 215 | + // The stream can be locked even if a test thread panicked: its state |
| 216 | + // will be ok |
| 217 | + TestWriterLock { |
| 218 | + inner: self.0.lock().unwrap_or_else(|e| e.into_inner()), |
| 219 | + } |
| 220 | + } |
248 | 221 | }
|
249 | 222 |
|
250 |
| - fn flush(&mut self) -> Result<()> { |
251 |
| - Ok(()) |
| 223 | + impl Writer for TestWriter { |
| 224 | + fn is_a_tty(&self) -> bool { |
| 225 | + false |
| 226 | + } |
| 227 | + |
| 228 | + fn lock(&self) -> Box<dyn WriterLock + '_> { |
| 229 | + Box::new(self.lock()) |
| 230 | + } |
| 231 | + |
| 232 | + fn terminal(&self) -> ColorableTerminal { |
| 233 | + ColorableTerminal::new(StreamSelector::TestWriter(self.clone())) |
| 234 | + } |
252 | 235 | }
|
253 |
| -} |
254 | 236 |
|
255 |
| -#[cfg(feature = "test")] |
256 |
| -impl StdoutSource for super::TestProcess { |
257 |
| - fn stdout(&self) -> Box<dyn Writer> { |
258 |
| - Box::new(TestWriter(self.stdout.clone())) |
| 237 | + impl Write for TestWriter { |
| 238 | + fn write(&mut self, buf: &[u8]) -> Result<usize> { |
| 239 | + self.lock().write(buf) |
| 240 | + } |
| 241 | + |
| 242 | + fn flush(&mut self) -> Result<()> { |
| 243 | + Ok(()) |
| 244 | + } |
259 | 245 | }
|
260 |
| -} |
261 | 246 |
|
262 |
| -#[cfg(feature = "test")] |
263 |
| -impl StderrSource for super::TestProcess { |
264 |
| - fn stderr(&self) -> Box<dyn Writer> { |
265 |
| - Box::new(TestWriter(self.stderr.clone())) |
| 247 | + impl StdoutSource for TestProcess { |
| 248 | + fn stdout(&self) -> Box<dyn Writer> { |
| 249 | + Box::new(TestWriter(self.stdout.clone())) |
| 250 | + } |
| 251 | + } |
| 252 | + |
| 253 | + impl StderrSource for TestProcess { |
| 254 | + fn stderr(&self) -> Box<dyn Writer> { |
| 255 | + Box::new(TestWriter(self.stderr.clone())) |
| 256 | + } |
266 | 257 | }
|
267 | 258 | }
|
0 commit comments