rustlings/src/verify.rs

86 lines
2.7 KiB
Rust
Raw Normal View History

2024-04-04 15:06:11 -04:00
use anyhow::Result;
2024-04-04 21:04:53 -04:00
use crossterm::style::{Attribute, ContentStyle, Stylize};
2024-04-04 15:06:11 -04:00
use std::io::{stdout, Write};
2024-03-31 10:55:33 -04:00
use crate::exercise::{Exercise, Mode, State};
2019-01-09 14:33:43 -05:00
2024-04-09 15:16:27 -04:00
pub enum VerifyState {
2024-04-01 12:38:01 -04:00
AllExercisesDone,
2024-04-09 15:16:27 -04:00
Failed(&'static Exercise),
2024-04-01 12:38:01 -04:00
}
// Verify that the provided container of Exercise objects
// can be compiled and run without any failures.
// Any such failures will be reported to the end user.
// If the Exercise being verified is a test, the verbose boolean
// determines whether or not the test harness outputs are displayed.
2024-04-09 15:16:27 -04:00
pub fn verify(
exercises: &'static [Exercise],
mut current_exercise_ind: usize,
) -> Result<VerifyState> {
2024-04-06 19:16:56 -04:00
while current_exercise_ind < exercises.len() {
let exercise = &exercises[current_exercise_ind];
println!(
"Progress: {current_exercise_ind}/{} ({:.1}%)\n",
exercises.len(),
current_exercise_ind as f32 / exercises.len() as f32 * 100.0,
);
2024-04-04 15:06:11 -04:00
let output = exercise.run()?;
2019-01-09 14:33:43 -05:00
2024-03-31 10:55:33 -04:00
{
let mut stdout = stdout().lock();
stdout.write_all(&output.stdout)?;
stdout.write_all(&output.stderr)?;
stdout.flush()?;
}
2024-04-04 15:06:11 -04:00
if !output.status.success() {
return Ok(VerifyState::Failed(exercise));
}
2024-04-04 15:06:11 -04:00
println!();
2024-04-04 18:49:22 -04:00
// TODO: Color
2024-04-04 15:06:11 -04:00
match exercise.mode {
2024-04-04 18:49:22 -04:00
Mode::Compile => println!("Successfully ran {exercise}!"),
Mode::Test => println!("Successfully tested {exercise}!"),
Mode::Clippy => println!("Successfully checked {exercise}!"),
2024-04-04 15:06:11 -04:00
}
2024-04-04 15:06:11 -04:00
if let State::Pending(context) = exercise.state()? {
println!(
"\nYou can keep working on this exercise,
or jump into the next one by removing the {} comment:\n",
2024-04-04 21:04:53 -04:00
"`I AM NOT DONE`".bold()
2024-04-04 15:06:11 -04:00
);
for context_line in context {
let formatted_line = if context_line.important {
2024-04-04 21:04:53 -04:00
format!("{}", context_line.line.bold())
2024-04-04 15:06:11 -04:00
} else {
context_line.line
};
println!(
"{:>2} {} {}",
2024-04-04 21:04:53 -04:00
ContentStyle {
foreground_color: Some(crossterm::style::Color::Blue),
background_color: None,
underline_color: None,
attributes: Attribute::Bold.into()
}
.apply(context_line.number),
"|".blue(),
2024-04-04 15:06:11 -04:00
formatted_line,
);
}
return Ok(VerifyState::Failed(exercise));
}
2024-04-06 19:16:56 -04:00
current_exercise_ind += 1;
}
2024-04-04 15:06:11 -04:00
Ok(VerifyState::AllExercisesDone)
}