Skip to content

Commit ea73af9

Browse files
committed
Separate initialization with a struct
1 parent fc5fc09 commit ea73af9

File tree

2 files changed

+74
-64
lines changed

2 files changed

+74
-64
lines changed

src/app_state.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
embedded::EMBEDDED_FILES,
2121
exercise::{Exercise, RunnableExercise},
2222
info_file::ExerciseInfo,
23-
term::{self, show_exercises_check_progress},
23+
term::{self, ExercisesCheckProgressVisualizer},
2424
};
2525

2626
const STATE_FILE_NAME: &str = ".rustlings-state.txt";
@@ -409,13 +409,12 @@ impl AppState {
409409
}
410410

411411
fn check_all_exercises_impl(&mut self, stdout: &mut StdoutLock) -> Result<Option<usize>> {
412-
stdout.write_all("Checking all exercises…\n".as_bytes())?;
413-
let next_exercise_ind = AtomicUsize::new(0);
414412
let term_width = terminal::size()
415413
.context("Failed to get the terminal size")?
416414
.0;
417-
clear_terminal(stdout)?;
415+
let mut progress_visualizer = ExercisesCheckProgressVisualizer::build(stdout, term_width)?;
418416

417+
let next_exercise_ind = AtomicUsize::new(0);
419418
let mut progresses = vec![ExerciseCheckProgress::None; self.exercises.len()];
420419

421420
thread::scope(|s| {
@@ -464,7 +463,7 @@ impl AppState {
464463

465464
while let Ok((exercise_ind, progress)) = exercise_progress_receiver.recv() {
466465
progresses[exercise_ind] = progress;
467-
show_exercises_check_progress(stdout, &progresses, term_width)?;
466+
progress_visualizer.update(&progresses)?;
468467
}
469468

470469
Ok::<_, Error>(())
@@ -487,7 +486,7 @@ impl AppState {
487486
// it could be because we exceeded the limit of open file descriptors.
488487
// Therefore, try running exercises with errors sequentially.
489488
progresses[exercise_ind] = ExerciseCheckProgress::Checking;
490-
show_exercises_check_progress(stdout, &progresses, term_width)?;
489+
progress_visualizer.update(&progresses)?;
491490

492491
let exercise = &self.exercises[exercise_ind];
493492
let success = exercise.run_exercise(None, &self.cmd_runner)?;
@@ -501,7 +500,7 @@ impl AppState {
501500
}
502501
self.set_status(exercise_ind, success)?;
503502

504-
show_exercises_check_progress(stdout, &progresses, term_width)?;
503+
progress_visualizer.update(&progresses)?;
505504
}
506505
}
507506
}

src/term.rs

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,74 @@ impl<'a> CountedWrite<'a> for StdoutLock<'a> {
8787
}
8888
}
8989

90+
pub struct ExercisesCheckProgressVisualizer<'a, 'b> {
91+
stdout: &'a mut StdoutLock<'b>,
92+
n_cols: usize,
93+
}
94+
95+
impl<'a, 'b> ExercisesCheckProgressVisualizer<'a, 'b> {
96+
pub fn build(stdout: &'a mut StdoutLock<'b>, term_width: u16) -> io::Result<Self> {
97+
clear_terminal(stdout)?;
98+
stdout.write_all("Checking all exercises…\n".as_bytes())?;
99+
100+
// Legend
101+
stdout.write_all(b"Color of exercise number: ")?;
102+
stdout.queue(SetForegroundColor(Color::Blue))?;
103+
stdout.write_all(b"Checking")?;
104+
stdout.queue(ResetColor)?;
105+
stdout.write_all(b" - ")?;
106+
stdout.queue(SetForegroundColor(Color::Green))?;
107+
stdout.write_all(b"Done")?;
108+
stdout.queue(ResetColor)?;
109+
stdout.write_all(b" - ")?;
110+
stdout.queue(SetForegroundColor(Color::Red))?;
111+
stdout.write_all(b"Pending")?;
112+
stdout.queue(ResetColor)?;
113+
stdout.write_all(b"\n")?;
114+
115+
// Exercise numbers with up to 3 digits.
116+
// +1 because the last column doesn't end with a whitespace.
117+
let n_cols = usize::from(term_width + 1) / 4;
118+
119+
Ok(Self { stdout, n_cols })
120+
}
121+
122+
pub fn update(&mut self, progresses: &[ExerciseCheckProgress]) -> io::Result<()> {
123+
self.stdout.queue(MoveTo(0, 2))?;
124+
125+
let mut exercise_num = 1;
126+
for exercise_progress in progresses {
127+
match exercise_progress {
128+
ExerciseCheckProgress::None => (),
129+
ExerciseCheckProgress::Checking => {
130+
self.stdout.queue(SetForegroundColor(Color::Blue))?;
131+
}
132+
ExerciseCheckProgress::Done => {
133+
self.stdout.queue(SetForegroundColor(Color::Green))?;
134+
}
135+
ExerciseCheckProgress::Pending => {
136+
self.stdout.queue(SetForegroundColor(Color::Red))?;
137+
}
138+
}
139+
140+
write!(self.stdout, "{exercise_num:<3}")?;
141+
self.stdout.queue(ResetColor)?;
142+
143+
if exercise_num != progresses.len() {
144+
if exercise_num % self.n_cols == 0 {
145+
self.stdout.write_all(b"\n")?;
146+
} else {
147+
self.stdout.write_all(b" ")?;
148+
}
149+
150+
exercise_num += 1;
151+
}
152+
}
153+
154+
self.stdout.flush()
155+
}
156+
}
157+
90158
pub fn progress_bar<'a>(
91159
writer: &mut impl CountedWrite<'a>,
92160
progress: u16,
@@ -137,63 +205,6 @@ pub fn progress_bar<'a>(
137205
write!(stdout, "] {progress:>3}/{total}")
138206
}
139207

140-
pub fn show_exercises_check_progress(
141-
stdout: &mut StdoutLock,
142-
progresses: &[ExerciseCheckProgress],
143-
term_width: u16,
144-
) -> io::Result<()> {
145-
stdout.queue(MoveTo(0, 0))?;
146-
147-
// Legend
148-
stdout.write_all(b"Color of exercise number: ")?;
149-
stdout.queue(SetForegroundColor(Color::Blue))?;
150-
stdout.write_all(b"Checking")?;
151-
stdout.queue(ResetColor)?;
152-
stdout.write_all(b" - ")?;
153-
stdout.queue(SetForegroundColor(Color::Green))?;
154-
stdout.write_all(b"Done")?;
155-
stdout.queue(ResetColor)?;
156-
stdout.write_all(b" - ")?;
157-
stdout.queue(SetForegroundColor(Color::Red))?;
158-
stdout.write_all(b"Pending")?;
159-
stdout.queue(ResetColor)?;
160-
stdout.write_all(b"\n")?;
161-
162-
// Exercise numbers with up to 3 digits.
163-
let n_cols = usize::from(term_width + 1) / 4;
164-
165-
let mut exercise_num = 1;
166-
for exercise_progress in progresses {
167-
match exercise_progress {
168-
ExerciseCheckProgress::None => (),
169-
ExerciseCheckProgress::Checking => {
170-
stdout.queue(SetForegroundColor(Color::Blue))?;
171-
}
172-
ExerciseCheckProgress::Done => {
173-
stdout.queue(SetForegroundColor(Color::Green))?;
174-
}
175-
ExerciseCheckProgress::Pending => {
176-
stdout.queue(SetForegroundColor(Color::Red))?;
177-
}
178-
}
179-
180-
write!(stdout, "{exercise_num:<3}")?;
181-
stdout.queue(ResetColor)?;
182-
183-
if exercise_num != progresses.len() {
184-
if exercise_num % n_cols == 0 {
185-
stdout.write_all(b"\n")?;
186-
} else {
187-
stdout.write_all(b" ")?;
188-
}
189-
190-
exercise_num += 1;
191-
}
192-
}
193-
194-
stdout.flush()
195-
}
196-
197208
pub fn clear_terminal(stdout: &mut StdoutLock) -> io::Result<()> {
198209
stdout
199210
.queue(MoveTo(0, 0))?

0 commit comments

Comments
 (0)