@@ -11,7 +11,7 @@ use std::ffi::OsStr;
1111use std:: fs;
1212use std:: io:: { self , prelude:: * } ;
1313use std:: path:: Path ;
14- use std:: process:: { Command , Stdio } ;
14+ use std:: process:: Command ;
1515use std:: sync:: atomic:: { AtomicBool , Ordering } ;
1616use std:: sync:: mpsc:: { channel, RecvTimeoutError } ;
1717use std:: sync:: { Arc , Mutex } ;
@@ -92,24 +92,25 @@ fn main() {
9292 println ! ( "\n {WELCOME}\n " ) ;
9393 }
9494
95- if !Path :: new ( "info.toml" ) . exists ( ) {
96- println ! (
97- "{} must be run from the rustlings directory" ,
98- std:: env:: current_exe( ) . unwrap( ) . to_str( ) . unwrap( )
99- ) ;
100- println ! ( "Try `cd rustlings/`!" ) ;
101- std:: process:: exit ( 1 ) ;
102- }
103-
104- if !rustc_exists ( ) {
95+ if which:: which ( "rustc" ) . is_err ( ) {
10596 println ! ( "We cannot find `rustc`." ) ;
10697 println ! ( "Try running `rustc --version` to diagnose your problem." ) ;
10798 println ! ( "For instructions on how to install Rust, check the README." ) ;
10899 std:: process:: exit ( 1 ) ;
109100 }
110101
111- let toml_str = & fs:: read_to_string ( "info.toml" ) . unwrap ( ) ;
112- let exercises = toml:: from_str :: < ExerciseList > ( toml_str) . unwrap ( ) . exercises ;
102+ let info_file = fs:: read_to_string ( "info.toml" ) . unwrap_or_else ( |e| {
103+ match e. kind ( ) {
104+ io:: ErrorKind :: NotFound => println ! (
105+ "The program must be run from the rustlings directory\n Try `cd rustlings/`!" ,
106+ ) ,
107+ _ => println ! ( "Failed to read the info.toml file: {e}" ) ,
108+ }
109+ std:: process:: exit ( 1 ) ;
110+ } ) ;
111+ let exercises = toml_edit:: de:: from_str :: < ExerciseList > ( & info_file)
112+ . unwrap ( )
113+ . exercises ;
113114 let verbose = args. nocapture ;
114115
115116 let command = args. command . unwrap_or_else ( || {
@@ -218,16 +219,13 @@ fn main() {
218219 println ! ( "Failed to write rust-project.json to disk for rust-analyzer" ) ;
219220 } else {
220221 println ! ( "Successfully generated rust-project.json" ) ;
221- println ! ( "rust-analyzer will now parse exercises, restart your language server or editor" )
222+ println ! ( "rust-analyzer will now parse exercises, restart your language server or editor" ) ;
222223 }
223224 }
224225
225226 Subcommands :: Watch { success_hints } => match watch ( & exercises, verbose, success_hints) {
226227 Err ( e) => {
227- println ! (
228- "Error: Could not watch your progress. Error message was {:?}." ,
229- e
230- ) ;
228+ println ! ( "Error: Could not watch your progress. Error message was {e:?}." ) ;
231229 println ! ( "Most likely you've run out of disk space or your 'inotify limit' has been reached." ) ;
232230 std:: process:: exit ( 1 ) ;
233231 }
@@ -295,7 +293,7 @@ fn spawn_watch_shell(
295293}
296294
297295fn find_exercise < ' a > ( name : & str , exercises : & ' a [ Exercise ] ) -> & ' a Exercise {
298- if name. eq ( "next" ) {
296+ if name == "next" {
299297 exercises
300298 . iter ( )
301299 . find ( |e| !e. looks_done ( ) )
@@ -341,15 +339,14 @@ fn watch(
341339
342340 clear_screen ( ) ;
343341
344- let to_owned_hint = |t : & Exercise | t. hint . to_owned ( ) ;
345342 let failed_exercise_hint = match verify (
346343 exercises. iter ( ) ,
347344 ( 0 , exercises. len ( ) ) ,
348345 verbose,
349346 success_hints,
350347 ) {
351348 Ok ( _) => return Ok ( WatchStatus :: Finished ) ,
352- Err ( exercise) => Arc :: new ( Mutex :: new ( Some ( to_owned_hint ( exercise) ) ) ) ,
349+ Err ( exercise) => Arc :: new ( Mutex :: new ( Some ( exercise. hint . clone ( ) ) ) ) ,
353350 } ;
354351 spawn_watch_shell ( Arc :: clone ( & failed_exercise_hint) , Arc :: clone ( & should_quit) ) ;
355352 loop {
@@ -386,7 +383,7 @@ fn watch(
386383 Err ( exercise) => {
387384 let mut failed_exercise_hint =
388385 failed_exercise_hint. lock ( ) . unwrap ( ) ;
389- * failed_exercise_hint = Some ( to_owned_hint ( exercise) ) ;
386+ * failed_exercise_hint = Some ( exercise. hint . clone ( ) ) ;
390387 }
391388 }
392389 }
@@ -406,19 +403,7 @@ fn watch(
406403 }
407404}
408405
409- fn rustc_exists ( ) -> bool {
410- Command :: new ( "rustc" )
411- . args ( [ "--version" ] )
412- . stdout ( Stdio :: null ( ) )
413- . stderr ( Stdio :: null ( ) )
414- . stdin ( Stdio :: null ( ) )
415- . spawn ( )
416- . and_then ( |mut child| child. wait ( ) )
417- . map ( |status| status. success ( ) )
418- . unwrap_or ( false )
419- }
420-
421- const DEFAULT_OUT : & str = r#"Thanks for installing Rustlings!
406+ const DEFAULT_OUT : & str = "Thanks for installing Rustlings!
422407
423408Is this your first time? Don't worry, Rustlings was made for beginners! We are
424409going to teach you a lot of things about Rust, but before we can get
@@ -444,7 +429,7 @@ started, here's a couple of notes about how Rustlings operates:
444429 autocompletion, run the command `rustlings lsp`.
445430
446431Got all that? Great! To get started, run `rustlings watch` in order to get the first
447- exercise. Make sure to have your editor open!"# ;
432+ exercise. Make sure to have your editor open!" ;
448433
449434const FENISH_LINE : & str = "+----------------------------------------------------+
450435| You made it to the Fe-nish line! |
0 commit comments