mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-07-01 00:45:17 +02:00
Make the output optional
This commit is contained in:
@ -19,8 +19,10 @@ pub const OUTPUT_CAPACITY: usize = 1 << 14;
|
||||
|
||||
// Run an exercise binary and append its output to the `output` buffer.
|
||||
// Compilation must be done before calling this method.
|
||||
fn run_bin(bin_name: &str, output: &mut Vec<u8>, target_dir: &Path) -> Result<bool> {
|
||||
writeln!(output, "{}", "Output".underlined())?;
|
||||
fn run_bin(bin_name: &str, mut output: Option<&mut Vec<u8>>, target_dir: &Path) -> Result<bool> {
|
||||
if let Some(output) = output.as_deref_mut() {
|
||||
writeln!(output, "{}", "Output".underlined())?;
|
||||
}
|
||||
|
||||
// 7 = "/debug/".len()
|
||||
let mut bin_path = PathBuf::with_capacity(target_dir.as_os_str().len() + 7 + bin_name.len());
|
||||
@ -28,19 +30,25 @@ fn run_bin(bin_name: &str, output: &mut Vec<u8>, target_dir: &Path) -> Result<bo
|
||||
bin_path.push("debug");
|
||||
bin_path.push(bin_name);
|
||||
|
||||
let success = run_cmd(Command::new(&bin_path), &bin_path.to_string_lossy(), output)?;
|
||||
let success = run_cmd(
|
||||
Command::new(&bin_path),
|
||||
&bin_path.to_string_lossy(),
|
||||
output.as_deref_mut(),
|
||||
)?;
|
||||
|
||||
if !success {
|
||||
// This output is important to show the user that something went wrong.
|
||||
// Otherwise, calling something like `exit(1)` in an exercise without further output
|
||||
// leaves the user confused about why the exercise isn't done yet.
|
||||
writeln!(
|
||||
output,
|
||||
"{}",
|
||||
"The exercise didn't run successfully (nonzero exit code)"
|
||||
.bold()
|
||||
.red(),
|
||||
)?;
|
||||
if let Some(output) = output {
|
||||
if !success {
|
||||
// This output is important to show the user that something went wrong.
|
||||
// Otherwise, calling something like `exit(1)` in an exercise without further output
|
||||
// leaves the user confused about why the exercise isn't done yet.
|
||||
writeln!(
|
||||
output,
|
||||
"{}",
|
||||
"The exercise didn't run successfully (nonzero exit code)"
|
||||
.bold()
|
||||
.red(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(success)
|
||||
@ -77,8 +85,15 @@ pub trait RunnableExercise {
|
||||
|
||||
// Compile, check and run the exercise or its solution (depending on `bin_name´).
|
||||
// The output is written to the `output` buffer after clearing it.
|
||||
fn run(&self, bin_name: &str, output: &mut Vec<u8>, target_dir: &Path) -> Result<bool> {
|
||||
output.clear();
|
||||
fn run(
|
||||
&self,
|
||||
bin_name: &str,
|
||||
mut output: Option<&mut Vec<u8>>,
|
||||
target_dir: &Path,
|
||||
) -> Result<bool> {
|
||||
if let Some(output) = output.as_deref_mut() {
|
||||
output.clear();
|
||||
}
|
||||
|
||||
// Developing the official Rustlings.
|
||||
let dev = DEBUG_PROFILE && in_official_repo();
|
||||
@ -90,7 +105,7 @@ pub trait RunnableExercise {
|
||||
description: "cargo build …",
|
||||
hide_warnings: false,
|
||||
target_dir,
|
||||
output,
|
||||
output: output.as_deref_mut(),
|
||||
dev,
|
||||
}
|
||||
.run()?;
|
||||
@ -99,7 +114,9 @@ pub trait RunnableExercise {
|
||||
}
|
||||
|
||||
// Discard the output of `cargo build` because it will be shown again by Clippy.
|
||||
output.clear();
|
||||
if let Some(output) = output.as_deref_mut() {
|
||||
output.clear();
|
||||
}
|
||||
|
||||
// `--profile test` is required to also check code with `[cfg(test)]`.
|
||||
let clippy_args: &[&str] = if self.strict_clippy() {
|
||||
@ -114,7 +131,7 @@ pub trait RunnableExercise {
|
||||
description: "cargo clippy …",
|
||||
hide_warnings: false,
|
||||
target_dir,
|
||||
output,
|
||||
output: output.as_deref_mut(),
|
||||
dev,
|
||||
}
|
||||
.run()?;
|
||||
@ -123,7 +140,7 @@ pub trait RunnableExercise {
|
||||
}
|
||||
|
||||
if !self.test() {
|
||||
return run_bin(bin_name, output, target_dir);
|
||||
return run_bin(bin_name, output.as_deref_mut(), target_dir);
|
||||
}
|
||||
|
||||
let test_success = CargoCmd {
|
||||
@ -134,12 +151,12 @@ pub trait RunnableExercise {
|
||||
// Hide warnings because they are shown by Clippy.
|
||||
hide_warnings: true,
|
||||
target_dir,
|
||||
output,
|
||||
output: output.as_deref_mut(),
|
||||
dev,
|
||||
}
|
||||
.run()?;
|
||||
|
||||
let run_success = run_bin(bin_name, output, target_dir)?;
|
||||
let run_success = run_bin(bin_name, output.as_deref_mut(), target_dir)?;
|
||||
|
||||
Ok(test_success && run_success)
|
||||
}
|
||||
@ -147,13 +164,13 @@ pub trait RunnableExercise {
|
||||
/// Compile, check and run the exercise.
|
||||
/// The output is written to the `output` buffer after clearing it.
|
||||
#[inline]
|
||||
fn run_exercise(&self, output: &mut Vec<u8>, target_dir: &Path) -> Result<bool> {
|
||||
fn run_exercise(&self, output: Option<&mut Vec<u8>>, target_dir: &Path) -> Result<bool> {
|
||||
self.run(self.name(), output, target_dir)
|
||||
}
|
||||
|
||||
/// Compile, check and run the exercise's solution.
|
||||
/// The output is written to the `output` buffer after clearing it.
|
||||
fn run_solution(&self, output: &mut Vec<u8>, target_dir: &Path) -> Result<bool> {
|
||||
fn run_solution(&self, output: Option<&mut Vec<u8>>, target_dir: &Path) -> Result<bool> {
|
||||
let name = self.name();
|
||||
let mut bin_name = String::with_capacity(name.len());
|
||||
bin_name.push_str(name);
|
||||
|
Reference in New Issue
Block a user