summaryrefslogtreecommitdiff
path: root/src/run.rs
blob: 2c9f99f6214364c4b5619cb529e17dbead77d561 (plain)
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
use anyhow::{bail, Result};
use std::io::{self, stdout, Write};
use std::time::Duration;

use crate::embedded::{WriteStrategy, EMBEDDED_FILES};
use crate::exercise::{Exercise, Mode};
use crate::verify::test;
use indicatif::ProgressBar;

// Invoke the rust compiler on the path of the given exercise,
// and run the ensuing binary.
// The verbose argument helps determine whether or not to show
// the output from the test harnesses (if the mode of the exercise is test)
pub fn run(exercise: &Exercise, verbose: bool) -> Result<()> {
    match exercise.mode {
        Mode::Test => test(exercise, verbose),
        Mode::Compile | Mode::Clippy => compile_and_run(exercise),
    }
}

// Resets the exercise by stashing the changes.
pub fn reset(exercise: &Exercise) -> io::Result<()> {
    EMBEDDED_FILES.write_exercise_to_disk(&exercise.path, WriteStrategy::Overwrite)
}

// Invoke the rust compiler on the path of the given exercise
// and run the ensuing binary.
// This is strictly for non-test binaries, so output is displayed
fn compile_and_run(exercise: &Exercise) -> Result<()> {
    let progress_bar = ProgressBar::new_spinner();
    progress_bar.set_message(format!("Running {exercise}..."));
    progress_bar.enable_steady_tick(Duration::from_millis(100));

    let output = exercise.run()?;
    progress_bar.finish_and_clear();

    stdout().write_all(&output.stdout)?;
    if !output.status.success() {
        stdout().write_all(&output.stderr)?;
        warn!("Ran {} with errors", exercise);
        bail!("TODO");
    }

    success!("Successfully ran {}", exercise);
    Ok(())
}