11use crate :: exercise:: { Exercise , ExerciseList } ;
22use crate :: project:: RustAnalyzerProject ;
3- use crate :: run:: run;
3+ use crate :: run:: { reset , run} ;
44use crate :: verify:: verify;
55use argh:: FromArgs ;
66use console:: Emoji ;
@@ -47,6 +47,7 @@ enum Subcommands {
4747 Verify ( VerifyArgs ) ,
4848 Watch ( WatchArgs ) ,
4949 Run ( RunArgs ) ,
50+ Reset ( ResetArgs ) ,
5051 Hint ( HintArgs ) ,
5152 List ( ListArgs ) ,
5253 Lsp ( LspArgs ) ,
@@ -71,6 +72,15 @@ struct RunArgs {
7172 name : String ,
7273}
7374
75+ #[ derive( FromArgs , PartialEq , Debug ) ]
76+ #[ argh( subcommand, name = "reset" ) ]
77+ /// Resets a single exercise using "git stash -- <filename>"
78+ struct ResetArgs {
79+ #[ argh( positional) ]
80+ /// the name of the exercise
81+ name : String ,
82+ }
83+
7484#[ derive( FromArgs , PartialEq , Debug ) ]
7585#[ argh( subcommand, name = "hint" ) ]
7686/// Returns a hint for the given exercise
@@ -85,7 +95,6 @@ struct HintArgs {
8595/// Enable rust-analyzer for exercises
8696struct LspArgs { }
8797
88-
8998#[ derive( FromArgs , PartialEq , Debug ) ]
9099#[ argh( subcommand, name = "list" ) ]
91100/// Lists the exercises available in Rustlings
@@ -164,7 +173,9 @@ fn main() {
164173 "Pending"
165174 } ;
166175 let solve_cond = {
167- ( e. looks_done ( ) && subargs. solved ) || ( !e. looks_done ( ) && subargs. unsolved ) || ( !subargs. solved && !subargs. unsolved )
176+ ( e. looks_done ( ) && subargs. solved )
177+ || ( !e. looks_done ( ) && subargs. unsolved )
178+ || ( !subargs. solved && !subargs. unsolved )
168179 } ;
169180 if solve_cond && ( filter_cond || subargs. filter . is_none ( ) ) {
170181 let line = if subargs. paths {
@@ -205,14 +216,21 @@ fn main() {
205216 run ( exercise, verbose) . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
206217 }
207218
219+ Subcommands :: Reset ( subargs) => {
220+ let exercise = find_exercise ( & subargs. name , & exercises) ;
221+
222+ reset ( exercise) . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
223+ }
224+
208225 Subcommands :: Hint ( subargs) => {
209226 let exercise = find_exercise ( & subargs. name , & exercises) ;
210227
211228 println ! ( "{}" , exercise. hint) ;
212229 }
213230
214231 Subcommands :: Verify ( _subargs) => {
215- verify ( & exercises, ( 0 , exercises. len ( ) ) , verbose) . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
232+ verify ( & exercises, ( 0 , exercises. len ( ) ) , verbose)
233+ . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
216234 }
217235
218236 Subcommands :: Lsp ( _subargs) => {
@@ -236,12 +254,18 @@ fn main() {
236254
237255 Subcommands :: Watch ( _subargs) => match watch ( & exercises, verbose) {
238256 Err ( e) => {
239- println ! ( "Error: Could not watch your progress. Error message was {:?}." , e) ;
257+ println ! (
258+ "Error: Could not watch your progress. Error message was {:?}." ,
259+ e
260+ ) ;
240261 println ! ( "Most likely you've run out of disk space or your 'inotify limit' has been reached." ) ;
241262 std:: process:: exit ( 1 ) ;
242263 }
243264 Ok ( WatchStatus :: Finished ) => {
244- println ! ( "{emoji} All exercises completed! {emoji}" , emoji = Emoji ( "🎉" , "★" ) ) ;
265+ println ! (
266+ "{emoji} All exercises completed! {emoji}" ,
267+ emoji = Emoji ( "🎉" , "★" )
268+ ) ;
245269 println ! ( "\n {}\n " , FENISH_LINE ) ;
246270 }
247271 Ok ( WatchStatus :: Unfinished ) => {
@@ -252,8 +276,10 @@ fn main() {
252276 }
253277}
254278
255-
256- fn spawn_watch_shell ( failed_exercise_hint : & Arc < Mutex < Option < String > > > , should_quit : Arc < AtomicBool > ) {
279+ fn spawn_watch_shell (
280+ failed_exercise_hint : & Arc < Mutex < Option < String > > > ,
281+ should_quit : Arc < AtomicBool > ,
282+ ) {
257283 let failed_exercise_hint = Arc :: clone ( failed_exercise_hint) ;
258284 println ! ( "Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here." ) ;
259285 thread:: spawn ( move || loop {
@@ -290,16 +316,22 @@ fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_q
290316
291317fn find_exercise < ' a > ( name : & str , exercises : & ' a [ Exercise ] ) -> & ' a Exercise {
292318 if name. eq ( "next" ) {
293- exercises. iter ( ) . find ( |e| !e. looks_done ( ) ) . unwrap_or_else ( || {
294- println ! ( "🎉 Congratulations! You have done all the exercises!" ) ;
295- println ! ( "🔚 There are no more exercises to do next!" ) ;
296- std:: process:: exit ( 1 )
297- } )
319+ exercises
320+ . iter ( )
321+ . find ( |e| !e. looks_done ( ) )
322+ . unwrap_or_else ( || {
323+ println ! ( "🎉 Congratulations! You have done all the exercises!" ) ;
324+ println ! ( "🔚 There are no more exercises to do next!" ) ;
325+ std:: process:: exit ( 1 )
326+ } )
298327 } else {
299- exercises. iter ( ) . find ( |e| e. name == name) . unwrap_or_else ( || {
300- println ! ( "No exercise found for '{}'!" , name) ;
301- std:: process:: exit ( 1 )
302- } )
328+ exercises
329+ . iter ( )
330+ . find ( |e| e. name == name)
331+ . unwrap_or_else ( || {
332+ println ! ( "No exercise found for '{}'!" , name) ;
333+ std:: process:: exit ( 1 )
334+ } )
303335 }
304336}
305337
@@ -337,8 +369,13 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
337369 let filepath = b. as_path ( ) . canonicalize ( ) . unwrap ( ) ;
338370 let pending_exercises = exercises
339371 . iter ( )
340- . find ( |e| filepath. ends_with ( & e. path ) ) . into_iter ( )
341- . chain ( exercises. iter ( ) . filter ( |e| !e. looks_done ( ) && !filepath. ends_with ( & e. path ) ) ) ;
372+ . find ( |e| filepath. ends_with ( & e. path ) )
373+ . into_iter ( )
374+ . chain (
375+ exercises
376+ . iter ( )
377+ . filter ( |e| !e. looks_done ( ) && !filepath. ends_with ( & e. path ) ) ,
378+ ) ;
342379 let num_done = exercises. iter ( ) . filter ( |e| e. looks_done ( ) ) . count ( ) ;
343380 clear_screen ( ) ;
344381 match verify ( pending_exercises, ( num_done, exercises. len ( ) ) , verbose) {
0 commit comments