2024-04-04 21:04:53 -04:00
|
|
|
use crate::consts::{DEFAULT_OUT, WELCOME};
|
2024-03-31 14:08:23 -04:00
|
|
|
use crate::embedded::{WriteStrategy, EMBEDDED_FILES};
|
2022-08-18 06:47:26 -04:00
|
|
|
use crate::exercise::{Exercise, ExerciseList};
|
2024-03-31 14:08:23 -04:00
|
|
|
use crate::run::run;
|
2024-04-04 21:04:53 -04:00
|
|
|
use crate::tui::tui;
|
2019-01-09 14:33:58 -05:00
|
|
|
use crate::verify::verify;
|
2024-04-01 12:38:01 -04:00
|
|
|
use anyhow::{bail, Context, Result};
|
2023-08-25 17:18:01 -04:00
|
|
|
use clap::{Parser, Subcommand};
|
2024-04-04 21:04:53 -04:00
|
|
|
use std::io::Write;
|
2019-03-16 22:15:09 -04:00
|
|
|
use std::path::Path;
|
2024-04-04 15:06:11 -04:00
|
|
|
use std::process::exit;
|
2024-04-01 12:38:01 -04:00
|
|
|
use verify::VerifyState;
|
2019-01-09 14:33:43 -05:00
|
|
|
|
2024-04-04 21:04:53 -04:00
|
|
|
mod consts;
|
2024-03-28 16:06:36 -04:00
|
|
|
mod embedded;
|
2019-04-11 16:41:24 -04:00
|
|
|
mod exercise;
|
2024-03-28 20:29:41 -04:00
|
|
|
mod init;
|
2019-01-09 14:33:43 -05:00
|
|
|
mod run;
|
2024-04-04 21:05:07 -04:00
|
|
|
mod state;
|
2024-04-04 21:04:53 -04:00
|
|
|
mod tui;
|
2019-01-09 14:33:58 -05:00
|
|
|
mod verify;
|
2018-05-14 12:41:58 -04:00
|
|
|
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
2023-08-25 17:18:01 -04:00
|
|
|
#[derive(Parser)]
|
|
|
|
#[command(version)]
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
struct Args {
|
2023-08-25 17:18:01 -04:00
|
|
|
#[command(subcommand)]
|
|
|
|
command: Option<Subcommands>,
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
}
|
|
|
|
|
2023-08-25 17:18:01 -04:00
|
|
|
#[derive(Subcommand)]
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
enum Subcommands {
|
2024-03-28 20:29:41 -04:00
|
|
|
/// Initialize Rustlings
|
|
|
|
Init,
|
2023-08-25 17:18:01 -04:00
|
|
|
/// Verify all exercises according to the recommended order
|
|
|
|
Verify,
|
2024-04-04 21:04:53 -04:00
|
|
|
/// Same as just running `rustlings` without a subcommand.
|
2024-04-04 15:06:11 -04:00
|
|
|
Watch,
|
2023-08-25 17:18:01 -04:00
|
|
|
/// Run/Test a single exercise
|
|
|
|
Run {
|
|
|
|
/// The name of the exercise
|
|
|
|
name: String,
|
|
|
|
},
|
2024-03-28 17:11:16 -04:00
|
|
|
/// Reset a single exercise
|
2023-08-25 17:18:01 -04:00
|
|
|
Reset {
|
|
|
|
/// The name of the exercise
|
|
|
|
name: String,
|
|
|
|
},
|
|
|
|
/// Return a hint for the given exercise
|
|
|
|
Hint {
|
|
|
|
/// The name of the exercise
|
|
|
|
name: String,
|
|
|
|
},
|
|
|
|
/// List the exercises available in Rustlings
|
|
|
|
List {
|
|
|
|
/// Show only the paths of the exercises
|
|
|
|
#[arg(short, long)]
|
|
|
|
paths: bool,
|
|
|
|
/// Show only the names of the exercises
|
|
|
|
#[arg(short, long)]
|
|
|
|
names: bool,
|
|
|
|
/// Provide a string to match exercise names.
|
|
|
|
/// Comma separated patterns are accepted
|
|
|
|
#[arg(short, long)]
|
|
|
|
filter: Option<String>,
|
|
|
|
/// Display only exercises not yet solved
|
|
|
|
#[arg(short, long)]
|
|
|
|
unsolved: bool,
|
|
|
|
/// Display only exercises that have been solved
|
|
|
|
#[arg(short, long)]
|
|
|
|
solved: bool,
|
|
|
|
},
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
}
|
|
|
|
|
2024-03-24 22:46:56 -04:00
|
|
|
fn main() -> Result<()> {
|
2023-08-25 17:18:01 -04:00
|
|
|
let args = Args::parse();
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
|
2023-08-25 17:18:01 -04:00
|
|
|
if args.command.is_none() {
|
2022-10-12 16:30:52 -04:00
|
|
|
println!("\n{WELCOME}\n");
|
2019-01-09 14:44:55 -05:00
|
|
|
}
|
2018-11-14 14:12:20 -05:00
|
|
|
|
2024-03-31 12:25:54 -04:00
|
|
|
which::which("cargo").context(
|
|
|
|
"Failed to find `cargo`.
|
2024-03-31 10:55:33 -04:00
|
|
|
Did you already install Rust?
|
2024-03-31 12:25:54 -04:00
|
|
|
Try running `cargo --version` to diagnose the problem.",
|
|
|
|
)?;
|
2019-11-11 11:15:14 -05:00
|
|
|
|
2024-03-31 10:55:33 -04:00
|
|
|
let exercises = ExerciseList::parse()?.exercises;
|
2019-04-11 16:41:24 -04:00
|
|
|
|
2024-03-28 20:29:41 -04:00
|
|
|
if matches!(args.command, Some(Subcommands::Init)) {
|
|
|
|
init::init_rustlings(&exercises).context("Initialization failed")?;
|
2024-03-28 20:52:05 -04:00
|
|
|
println!(
|
|
|
|
"\nDone initialization!\n
|
|
|
|
Run `cd rustlings` to go into the generated directory.
|
|
|
|
Then run `rustlings` for further instructions on getting started."
|
|
|
|
);
|
2024-03-28 20:29:41 -04:00
|
|
|
return Ok(());
|
|
|
|
} else if !Path::new("exercises").is_dir() {
|
|
|
|
println!(
|
|
|
|
"\nThe `exercises` directory wasn't found in the current directory.
|
2024-03-28 20:52:05 -04:00
|
|
|
If you are just starting with Rustlings, run the command `rustlings init` to initialize it."
|
2024-03-28 20:29:41 -04:00
|
|
|
);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2024-04-04 21:04:53 -04:00
|
|
|
match args.command {
|
|
|
|
None | Some(Subcommands::Watch) => {
|
|
|
|
println!("{DEFAULT_OUT}\n");
|
|
|
|
tui(&exercises)?;
|
|
|
|
}
|
2024-03-28 20:29:41 -04:00
|
|
|
// `Init` is handled above.
|
2024-04-04 21:04:53 -04:00
|
|
|
Some(Subcommands::Init) => (),
|
|
|
|
Some(Subcommands::List {
|
2023-08-25 17:18:01 -04:00
|
|
|
paths,
|
|
|
|
names,
|
|
|
|
filter,
|
|
|
|
unsolved,
|
|
|
|
solved,
|
2024-04-04 21:04:53 -04:00
|
|
|
}) => {
|
2023-08-25 17:18:01 -04:00
|
|
|
if !paths && !names {
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
|
|
|
|
}
|
|
|
|
let mut exercises_done: u16 = 0;
|
2024-03-23 16:56:40 -04:00
|
|
|
let lowercase_filter = filter
|
|
|
|
.as_ref()
|
|
|
|
.map(|s| s.to_lowercase())
|
|
|
|
.unwrap_or_default();
|
|
|
|
let filters = lowercase_filter
|
|
|
|
.split(',')
|
|
|
|
.filter_map(|f| {
|
|
|
|
let f = f.trim();
|
|
|
|
if f.is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(f)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
for exercise in &exercises {
|
2024-03-24 13:47:27 -04:00
|
|
|
let fname = exercise.path.to_string_lossy();
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
let filter_cond = filters
|
2024-03-23 16:56:40 -04:00
|
|
|
.iter()
|
|
|
|
.any(|f| exercise.name.contains(f) || fname.contains(f));
|
2024-03-31 12:25:54 -04:00
|
|
|
let looks_done = exercise.looks_done()?;
|
2024-03-24 13:50:46 -04:00
|
|
|
let status = if looks_done {
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
exercises_done += 1;
|
|
|
|
"Done"
|
2020-12-12 13:48:25 -05:00
|
|
|
} else {
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
"Pending"
|
2020-12-12 13:48:25 -05:00
|
|
|
};
|
2024-03-24 13:50:46 -04:00
|
|
|
let solve_cond =
|
|
|
|
(looks_done && solved) || (!looks_done && unsolved) || (!solved && !unsolved);
|
2023-08-25 17:18:01 -04:00
|
|
|
if solve_cond && (filter_cond || filter.is_none()) {
|
|
|
|
let line = if paths {
|
2022-10-12 16:30:52 -04:00
|
|
|
format!("{fname}\n")
|
2023-08-25 17:18:01 -04:00
|
|
|
} else if names {
|
2024-03-23 16:56:40 -04:00
|
|
|
format!("{}\n", exercise.name)
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
} else {
|
2024-03-23 16:56:40 -04:00
|
|
|
format!("{:<17}\t{fname:<46}\t{status:<7}\n", exercise.name)
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
};
|
|
|
|
// Somehow using println! leads to the binary panicking
|
|
|
|
// when its output is piped.
|
|
|
|
// So, we're handling a Broken Pipe error and exiting with 0 anyway
|
|
|
|
let stdout = std::io::stdout();
|
|
|
|
{
|
|
|
|
let mut handle = stdout.lock();
|
|
|
|
handle.write_all(line.as_bytes()).unwrap_or_else(|e| {
|
|
|
|
match e.kind() {
|
2024-03-31 12:25:54 -04:00
|
|
|
std::io::ErrorKind::BrokenPipe => exit(0),
|
|
|
|
_ => exit(1),
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2020-12-12 13:48:25 -05:00
|
|
|
}
|
2024-03-23 16:56:40 -04:00
|
|
|
}
|
|
|
|
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
let percentage_progress = exercises_done as f32 / exercises.len() as f32 * 100.0;
|
|
|
|
println!(
|
2022-10-03 08:56:46 -04:00
|
|
|
"Progress: You completed {} / {} exercises ({:.1} %).",
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
exercises_done,
|
|
|
|
exercises.len(),
|
|
|
|
percentage_progress
|
|
|
|
);
|
2024-03-31 12:25:54 -04:00
|
|
|
exit(0);
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
}
|
2024-04-04 21:04:53 -04:00
|
|
|
Some(Subcommands::Run { name }) => {
|
2024-03-31 12:25:54 -04:00
|
|
|
let exercise = find_exercise(&name, &exercises)?;
|
2024-04-04 15:06:11 -04:00
|
|
|
run(exercise).unwrap_or_else(|_| exit(1));
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
}
|
2024-04-04 21:04:53 -04:00
|
|
|
Some(Subcommands::Reset { name }) => {
|
2024-03-31 12:25:54 -04:00
|
|
|
let exercise = find_exercise(&name, &exercises)?;
|
2024-03-31 14:08:23 -04:00
|
|
|
EMBEDDED_FILES
|
|
|
|
.write_exercise_to_disk(&exercise.path, WriteStrategy::Overwrite)
|
|
|
|
.with_context(|| format!("Failed to reset the exercise {exercise}"))?;
|
2024-03-30 16:13:28 -04:00
|
|
|
println!("The file {} has been reset!", exercise.path.display());
|
2022-08-17 10:31:53 -04:00
|
|
|
}
|
2024-04-04 21:04:53 -04:00
|
|
|
Some(Subcommands::Hint { name }) => {
|
2024-03-31 12:25:54 -04:00
|
|
|
let exercise = find_exercise(&name, &exercises)?;
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
println!("{}", exercise.hint);
|
|
|
|
}
|
2024-04-04 21:04:53 -04:00
|
|
|
Some(Subcommands::Verify) => match verify(&exercises, (0, exercises.len()))? {
|
2024-04-01 12:38:01 -04:00
|
|
|
VerifyState::AllExercisesDone => println!("All exercises done!"),
|
|
|
|
VerifyState::Failed(exercise) => bail!("Exercise {exercise} failed"),
|
|
|
|
},
|
2018-11-26 05:10:38 -05:00
|
|
|
}
|
2024-03-24 22:46:56 -04:00
|
|
|
|
|
|
|
Ok(())
|
2018-05-06 12:59:50 -04:00
|
|
|
}
|
|
|
|
|
2024-03-31 12:25:54 -04:00
|
|
|
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> Result<&'a Exercise> {
|
2024-03-26 12:49:55 -04:00
|
|
|
if name == "next" {
|
2024-03-31 12:25:54 -04:00
|
|
|
for exercise in exercises {
|
|
|
|
if !exercise.looks_done()? {
|
|
|
|
return Ok(exercise);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("🎉 Congratulations! You have done all the exercises!");
|
|
|
|
println!("🔚 There are no more exercises to do next!");
|
|
|
|
exit(0);
|
2021-06-30 06:05:49 -04:00
|
|
|
}
|
2024-03-31 12:25:54 -04:00
|
|
|
|
|
|
|
exercises
|
|
|
|
.iter()
|
|
|
|
.find(|e| e.name == name)
|
|
|
|
.with_context(|| format!("No exercise found for '{name}'!"))
|
feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.
I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-20 06:46:49 -04:00
|
|
|
}
|