diff --git a/info.toml b/info.toml index c085e89c..d35b5702 100644 --- a/info.toml +++ b/info.toml @@ -1,3 +1,35 @@ +welcome_message = """Is this your first time? Don't worry, Rustlings was made for beginners! We are +going to teach you a lot of things about Rust, but before we can get +started, here's a couple of notes about how Rustlings operates: + +1. The central concept behind Rustlings is that you solve exercises. These + exercises usually have some sort of syntax error in them, which will cause + them to fail compilation or testing. Sometimes there's a logic error instead + of a syntax error. No matter what error, it's your job to find it and fix it! + You'll know when you fixed it because then, the exercise will compile and + Rustlings will be able to move on to the next exercise. +2. If you run Rustlings in watch mode (which we recommend), it'll automatically + start with the first exercise. Don't get confused by an error message popping + up as soon as you run Rustlings! This is part of the exercise that you're + supposed to solve, so open the exercise file in an editor and start your + detective work! +3. If you're stuck on an exercise, there is a helpful hint you can view by typing + 'hint' (in watch mode), or running `rustlings hint exercise_name`. +4. If an exercise doesn't make sense to you, feel free to open an issue on GitHub! + (https://github.com/rust-lang/rustlings/issues/new). We look at every issue, + and sometimes, other learners do too so you can help each other out! + +Got all that? Great! To get started, run `rustlings watch` in order to get the first exercise. +Make sure to have your editor open in the `rustlings` directory!""" + +final_message = """We hope you enjoyed learning about the various aspects of Rust! +If you noticed any issues, please don't hesitate to report them to our repo. +You can also contribute your own exercises to help the greater community! + +Before reporting an issue or contributing, please read our guidelines: +https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md +""" + # INTRO [[exercises]] diff --git a/src/consts.rs b/src/consts.rs deleted file mode 100644 index 40bf150f..00000000 --- a/src/consts.rs +++ /dev/null @@ -1,59 +0,0 @@ -pub const WELCOME: &str = r" welcome to... - _ _ _ - _ __ _ _ ___| |_| (_)_ __ __ _ ___ - | '__| | | / __| __| | | '_ \ / _` / __| - | | | |_| \__ \ |_| | | | | | (_| \__ \ - |_| \__,_|___/\__|_|_|_| |_|\__, |___/ - |___/"; - -pub const DEFAULT_OUT: &str = - "Is this your first time? Don't worry, Rustlings was made for beginners! We are -going to teach you a lot of things about Rust, but before we can get -started, here's a couple of notes about how Rustlings operates: - -1. The central concept behind Rustlings is that you solve exercises. These - exercises usually have some sort of syntax error in them, which will cause - them to fail compilation or testing. Sometimes there's a logic error instead - of a syntax error. No matter what error, it's your job to find it and fix it! - You'll know when you fixed it because then, the exercise will compile and - Rustlings will be able to move on to the next exercise. -2. If you run Rustlings in watch mode (which we recommend), it'll automatically - start with the first exercise. Don't get confused by an error message popping - up as soon as you run Rustlings! This is part of the exercise that you're - supposed to solve, so open the exercise file in an editor and start your - detective work! -3. If you're stuck on an exercise, there is a helpful hint you can view by typing - 'hint' (in watch mode), or running `rustlings hint exercise_name`. -4. If an exercise doesn't make sense to you, feel free to open an issue on GitHub! - (https://github.com/rust-lang/rustlings/issues/new). We look at every issue, - and sometimes, other learners do too so you can help each other out! - -Got all that? Great! To get started, run `rustlings watch` in order to get the first exercise. -Make sure to have your editor open in the `rustlings` directory!"; - -pub const FENISH_LINE: &str = "+----------------------------------------------------+ -| You made it to the Fe-nish line! | -+-------------------------- ------------------------+ - \\/\x1b[31m - ▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒ - ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ - ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ - ░░▒▒▒▒░░▒▒ ▒▒ ▒▒ ▒▒ ▒▒░░▒▒▒▒ - ▓▓▓▓▓▓▓▓ ▓▓ ▓▓██ ▓▓ ▓▓██ ▓▓ ▓▓▓▓▓▓▓▓ - ▒▒▒▒ ▒▒ ████ ▒▒ ████ ▒▒░░ ▒▒▒▒ - ▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒ - ▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒▒▒▒▒▒▒▒ - ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ - ▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒ - ▒▒ ▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒ ▒▒ - ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ - ▒▒ ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒ - ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ - ▒▒ ▒▒ ▒▒ ▒▒\x1b[0m - -We hope you enjoyed learning about the various aspects of Rust! -If you noticed any issues, please don't hesitate to report them to our repo. -You can also contribute your own exercises to help the greater community! - -Before reporting an issue or contributing, please read our guidelines: -https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md"; diff --git a/src/exercise.rs b/src/exercise.rs index f01c6fcc..d28f4dbe 100644 --- a/src/exercise.rs +++ b/src/exercise.rs @@ -24,6 +24,10 @@ pub enum Mode { #[derive(Deserialize)] #[serde(deny_unknown_fields)] pub struct InfoFile { + // TODO + pub welcome_message: Option, + // TODO + pub final_message: Option, pub exercises: Vec, } @@ -39,10 +43,7 @@ impl InfoFile { .context("Failed to parse `info.toml`")?; if slf.exercises.is_empty() { - panic!( - "There are no exercises yet! -If you are developing third-party exercises, add at least one exercise before testing." - ); + panic!("{NO_EXERCISES_ERR}"); } Ok(slf) @@ -119,3 +120,6 @@ impl Display for Exercise { self.path.fmt(f) } } + +const NO_EXERCISES_ERR: &str = "There are no exercises yet! +If you are developing third-party exercises, add at least one exercise before testing."; diff --git a/src/init.rs b/src/init.rs index bc561eaf..44747438 100644 --- a/src/init.rs +++ b/src/init.rs @@ -36,47 +36,33 @@ publish = false } fn create_gitignore() -> io::Result<()> { - let gitignore = b"/target -/.rustlings-state.json"; OpenOptions::new() .create_new(true) .write(true) .open(".gitignore")? - .write_all(gitignore) + .write_all(GITIGNORE) } fn create_vscode_dir() -> Result<()> { create_dir(".vscode").context("Failed to create the directory `.vscode`")?; - let vs_code_extensions_json = br#"{"recommendations":["rust-lang.rust-analyzer"]}"#; OpenOptions::new() .create_new(true) .write(true) .open(".vscode/extensions.json")? - .write_all(vs_code_extensions_json)?; + .write_all(VS_CODE_EXTENSIONS_JSON)?; Ok(()) } pub fn init(exercises: &[Exercise]) -> Result<()> { if Path::new("exercises").is_dir() && Path::new("Cargo.toml").is_file() { - bail!( - "A directory with the name `exercises` and a file with the name `Cargo.toml` already exist -in the current directory. It looks like Rustlings was already initialized here. -Run `rustlings` for instructions on getting started with the exercises. - -If you didn't already initialize Rustlings, please initialize it in another directory." - ); + bail!(PROBABLY_IN_RUSTLINGS_DIR_ERR); } let rustlings_path = Path::new("rustlings"); if let Err(e) = create_dir(rustlings_path) { if e.kind() == ErrorKind::AlreadyExists { - bail!( - "A directory with the name `rustlings` already exists in the current directory. -You probably already initialized Rustlings. -Run `cd rustlings` -Then run `rustlings` again" - ); + bail!(RUSTLINGS_DIR_ALREADY_EXISTS_ERR); } return Err(e.into()); } @@ -96,3 +82,21 @@ Then run `rustlings` again" Ok(()) } + +const GITIGNORE: &[u8] = b"/target +/.rustlings-state.json"; + +const VS_CODE_EXTENSIONS_JSON: &[u8] = br#"{"recommendations":["rust-lang.rust-analyzer"]}"#; + +const PROBABLY_IN_RUSTLINGS_DIR_ERR: &str = + "A directory with the name `exercises` and a file with the name `Cargo.toml` already exist +in the current directory. It looks like Rustlings was already initialized here. +Run `rustlings` for instructions on getting started with the exercises. + +If you didn't already initialize Rustlings, please initialize it in another directory."; + +const RUSTLINGS_DIR_ALREADY_EXISTS_ERR: &str = + "A directory with the name `rustlings` already exists in the current directory. +You probably already initialized Rustlings. +Run `cd rustlings` +Then run `rustlings` again"; diff --git a/src/main.rs b/src/main.rs index 7bc10ac8..fdbb710c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ use clap::{Parser, Subcommand}; use std::{path::Path, process::exit}; mod app_state; -mod consts; mod embedded; mod exercise; mod init; @@ -14,7 +13,6 @@ mod watch; use self::{ app_state::AppState, - consts::WELCOME, exercise::InfoFile, init::init, list::list, @@ -54,11 +52,7 @@ enum Subcommands { fn main() -> Result<()> { let args = Args::parse(); - which::which("cargo").context( - "Failed to find `cargo`. -Did you already install Rust? -Try running `cargo --version` to diagnose the problem.", - )?; + which::which("cargo").context(CARGO_NOT_FOUND_ERR)?; let mut info_file = InfoFile::parse()?; info_file.exercises.shrink_to_fit(); @@ -66,20 +60,11 @@ Try running `cargo --version` to diagnose the problem.", if matches!(args.command, Some(Subcommands::Init)) { init(&exercises).context("Initialization failed")?; - println!( - "\nDone initialization!\n -Run `cd rustlings` to go into the generated directory. -Then run `rustlings` for further instructions on getting started." - ); + + println!("{POST_INIT_MSG}"); return Ok(()); } else if !Path::new("exercises").is_dir() { - println!( - " -{WELCOME} - -The `exercises` directory wasn't found in the current directory. -If you are just starting with Rustlings, run the command `rustlings init` to initialize it." - ); + println!("{PRE_INIT_MSG}"); exit(1); } @@ -118,3 +103,45 @@ If you are just starting with Rustlings, run the command `rustlings init` to ini Ok(()) } + +const CARGO_NOT_FOUND_ERR: &str = "Failed to find `cargo`. +Did you already install Rust? +Try running `cargo --version` to diagnose the problem."; + +const PRE_INIT_MSG: &str = r" + welcome to... + _ _ _ + _ __ _ _ ___| |_| (_)_ __ __ _ ___ + | '__| | | / __| __| | | '_ \ / _` / __| + | | | |_| \__ \ |_| | | | | | (_| \__ \ + |_| \__,_|___/\__|_|_|_| |_|\__, |___/ + |___/ + +The `exercises` directory wasn't found in the current directory. +If you are just starting with Rustlings, run the command `rustlings init` to initialize it."; + +const POST_INIT_MSG: &str = " +Done initialization! + +Run `cd rustlings` to go into the generated directory. +Then run `rustlings` for further instructions on getting started."; + +const FENISH_LINE: &str = "+----------------------------------------------------+ +| You made it to the Fe-nish line! | ++-------------------------- ------------------------+ + \\/\x1b[31m + ▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒ + ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ + ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ + ░░▒▒▒▒░░▒▒ ▒▒ ▒▒ ▒▒ ▒▒░░▒▒▒▒ + ▓▓▓▓▓▓▓▓ ▓▓ ▓▓██ ▓▓ ▓▓██ ▓▓ ▓▓▓▓▓▓▓▓ + ▒▒▒▒ ▒▒ ████ ▒▒ ████ ▒▒░░ ▒▒▒▒ + ▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒ + ▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒ + ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ + ▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒ + ▒▒ ▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒ ▒▒ + ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ + ▒▒ ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒ + ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ + ▒▒ ▒▒ ▒▒ ▒▒\x1b[0m"; diff --git a/src/watch.rs b/src/watch.rs index 929275f1..bfa0f88a 100644 --- a/src/watch.rs +++ b/src/watch.rs @@ -89,10 +89,12 @@ pub fn watch(app_state: &mut AppState) -> Result { } } - watch_state.into_writer().write_all(b" -We hope you're enjoying learning Rust! -If you want to continue working on the exercises at a later point, you can simply run `rustlings` again. -")?; + watch_state.into_writer().write_all(QUIT_MSG)?; Ok(WatchExit::Shutdown) } + +const QUIT_MSG: &[u8] = b" +We hope you're enjoying learning Rust! +If you want to continue working on the exercises at a later point, you can simply run `rustlings` again. +";