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