1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
use anyhow::Result;
use console::style;
use std::io::{stdout, Write};
use crate::exercise::{Exercise, Mode, State};
pub enum VerifyState<'a> {
AllExercisesDone,
Failed(&'a Exercise),
}
// 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.
pub fn verify<'a>(
pending_exercises: impl IntoIterator<Item = &'a Exercise>,
progress: (usize, usize),
) -> Result<VerifyState<'a>> {
let (mut num_done, total) = progress;
println!(
"Progress: {num_done}/{total} ({:.1}%)\n",
num_done as f32 / total as f32 * 100.0,
);
for exercise in pending_exercises {
let output = exercise.run()?;
{
let mut stdout = stdout().lock();
stdout.write_all(&output.stdout)?;
stdout.write_all(&output.stderr)?;
stdout.flush()?;
}
if !output.status.success() {
return Ok(VerifyState::Failed(exercise));
}
println!();
match exercise.mode {
Mode::Compile => success!("Successfully ran {}!", exercise),
Mode::Test => success!("Successfully tested {}!", exercise),
Mode::Clippy => success!("Successfully checked {}!", exercise),
}
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",
style("`I AM NOT DONE`").bold()
);
for context_line in context {
let formatted_line = if context_line.important {
format!("{}", style(context_line.line).bold())
} else {
context_line.line
};
println!(
"{:>2} {} {}",
style(context_line.number).blue().bold(),
style("|").blue(),
formatted_line,
);
}
return Ok(VerifyState::Failed(exercise));
}
num_done += 1;
println!(
"Progress: {num_done}/{total} ({:.1}%)\n",
num_done as f32 / total as f32 * 100.0,
);
}
Ok(VerifyState::AllExercisesDone)
}
|