1 use std::error::Error;
2 use std::fs::File;
3 use std::io::{Read, Write};
4 use std::path::Path;
5 use std::process::{Command, Stdio};
6
7 pub struct Output {
8 pub success: bool,
9 pub stdout: Vec<u8>,
10 pub stderr: Vec<u8>,
11 }
12
run( compiled: &str, unsafe_main: unsafe fn( stdin: &mut dyn Read, stdout: &mut dyn Write, ) -> Result<(), Box<dyn Error>>, input: &Path, ) -> Output13 pub fn run(
14 compiled: &str,
15 unsafe_main: unsafe fn(
16 stdin: &mut dyn Read,
17 stdout: &mut dyn Write,
18 ) -> Result<(), Box<dyn Error>>,
19 input: &Path,
20 ) -> Output {
21 if cfg!(miri) {
22 let mut input = File::open(input).unwrap();
23 let mut stdout = Vec::new();
24 let result = unsafe { unsafe_main(&mut input, &mut stdout) };
25
26 Output {
27 success: result.is_ok(),
28 stdout,
29 stderr: result
30 .err()
31 .as_ref()
32 .map_or_else(String::new, ToString::to_string)
33 .into(),
34 }
35 } else {
36 let output = Command::new(compiled)
37 .arg(input)
38 .stdin(Stdio::null())
39 .output()
40 .unwrap();
41
42 Output {
43 success: output.status.success(),
44 stdout: output.stdout,
45 stderr: output.stderr,
46 }
47 }
48 }
49