1- use crate :: exercise:: { Exercise , ExerciseList } ;
21use crate :: project:: RustAnalyzerProject ;
32use crate :: run:: run;
43use crate :: verify:: verify;
4+ use crate :: {
5+ exercise:: { Exercise , ExerciseList } ,
6+ run:: reset,
7+ } ;
58use argh:: FromArgs ;
69use console:: Emoji ;
710use notify:: DebouncedEvent ;
@@ -47,6 +50,7 @@ enum Subcommands {
4750 Verify ( VerifyArgs ) ,
4851 Watch ( WatchArgs ) ,
4952 Run ( RunArgs ) ,
53+ Reset ( ResetArgs ) ,
5054 Hint ( HintArgs ) ,
5155 List ( ListArgs ) ,
5256 Lsp ( LspArgs ) ,
@@ -71,6 +75,15 @@ struct RunArgs {
7175 name : String ,
7276}
7377
78+ #[ derive( FromArgs , PartialEq , Debug ) ]
79+ #[ argh( subcommand, name = "reset" ) ]
80+ /// Resets a single exercise
81+ struct ResetArgs {
82+ #[ argh( positional) ]
83+ /// the name of the exercise
84+ name : String ,
85+ }
86+
7487#[ derive( FromArgs , PartialEq , Debug ) ]
7588#[ argh( subcommand, name = "hint" ) ]
7689/// Returns a hint for the given exercise
@@ -85,7 +98,6 @@ struct HintArgs {
8598/// Enable rust-analyzer for exercises
8699struct LspArgs { }
87100
88-
89101#[ derive( FromArgs , PartialEq , Debug ) ]
90102#[ argh( subcommand, name = "list" ) ]
91103/// Lists the exercises available in Rustlings
@@ -164,7 +176,9 @@ fn main() {
164176 "Pending"
165177 } ;
166178 let solve_cond = {
167- ( e. looks_done ( ) && subargs. solved ) || ( !e. looks_done ( ) && subargs. unsolved ) || ( !subargs. solved && !subargs. unsolved )
179+ ( e. looks_done ( ) && subargs. solved )
180+ || ( !e. looks_done ( ) && subargs. unsolved )
181+ || ( !subargs. solved && !subargs. unsolved )
168182 } ;
169183 if solve_cond && ( filter_cond || subargs. filter . is_none ( ) ) {
170184 let line = if subargs. paths {
@@ -205,14 +219,21 @@ fn main() {
205219 run ( exercise, verbose) . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
206220 }
207221
222+ Subcommands :: Reset ( subargs) => {
223+ let exercise = find_exercise ( & subargs. name , & exercises) ;
224+
225+ reset ( exercise) . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
226+ }
227+
208228 Subcommands :: Hint ( subargs) => {
209229 let exercise = find_exercise ( & subargs. name , & exercises) ;
210230
211231 println ! ( "{}" , exercise. hint) ;
212232 }
213233
214234 Subcommands :: Verify ( _subargs) => {
215- verify ( & exercises, ( 0 , exercises. len ( ) ) , verbose) . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
235+ verify ( & exercises, ( 0 , exercises. len ( ) ) , verbose)
236+ . unwrap_or_else ( |_| std:: process:: exit ( 1 ) ) ;
216237 }
217238
218239 Subcommands :: Lsp ( _subargs) => {
@@ -236,12 +257,18 @@ fn main() {
236257
237258 Subcommands :: Watch ( _subargs) => match watch ( & exercises, verbose) {
238259 Err ( e) => {
239- println ! ( "Error: Could not watch your progress. Error message was {:?}." , e) ;
260+ println ! (
261+ "Error: Could not watch your progress. Error message was {:?}." ,
262+ e
263+ ) ;
240264 println ! ( "Most likely you've run out of disk space or your 'inotify limit' has been reached." ) ;
241265 std:: process:: exit ( 1 ) ;
242266 }
243267 Ok ( WatchStatus :: Finished ) => {
244- println ! ( "{emoji} All exercises completed! {emoji}" , emoji = Emoji ( "🎉" , "★" ) ) ;
268+ println ! (
269+ "{emoji} All exercises completed! {emoji}" ,
270+ emoji = Emoji ( "🎉" , "★" )
271+ ) ;
245272 println ! ( "\n {}\n " , FENISH_LINE ) ;
246273 }
247274 Ok ( WatchStatus :: Unfinished ) => {
@@ -252,8 +279,10 @@ fn main() {
252279 }
253280}
254281
255-
256- fn spawn_watch_shell ( failed_exercise_hint : & Arc < Mutex < Option < String > > > , should_quit : Arc < AtomicBool > ) {
282+ fn spawn_watch_shell (
283+ failed_exercise_hint : & Arc < Mutex < Option < String > > > ,
284+ should_quit : Arc < AtomicBool > ,
285+ ) {
257286 let failed_exercise_hint = Arc :: clone ( failed_exercise_hint) ;
258287 println ! ( "Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here." ) ;
259288 thread:: spawn ( move || loop {
@@ -290,16 +319,22 @@ fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_q
290319
291320fn find_exercise < ' a > ( name : & str , exercises : & ' a [ Exercise ] ) -> & ' a Exercise {
292321 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- } )
322+ exercises
323+ . iter ( )
324+ . find ( |e| !e. looks_done ( ) )
325+ . unwrap_or_else ( || {
326+ println ! ( "🎉 Congratulations! You have done all the exercises!" ) ;
327+ println ! ( "🔚 There are no more exercises to do next!" ) ;
328+ std:: process:: exit ( 1 )
329+ } )
298330 } 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- } )
331+ exercises
332+ . iter ( )
333+ . find ( |e| e. name == name)
334+ . unwrap_or_else ( || {
335+ println ! ( "No exercise found for '{}'!" , name) ;
336+ std:: process:: exit ( 1 )
337+ } )
303338 }
304339}
305340
@@ -337,8 +372,13 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
337372 let filepath = b. as_path ( ) . canonicalize ( ) . unwrap ( ) ;
338373 let pending_exercises = exercises
339374 . 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 ) ) ) ;
375+ . find ( |e| filepath. ends_with ( & e. path ) )
376+ . into_iter ( )
377+ . chain (
378+ exercises
379+ . iter ( )
380+ . filter ( |e| !e. looks_done ( ) && !filepath. ends_with ( & e. path ) ) ,
381+ ) ;
342382 let num_done = exercises. iter ( ) . filter ( |e| e. looks_done ( ) ) . count ( ) ;
343383 clear_screen ( ) ;
344384 match verify ( pending_exercises, ( num_done, exercises. len ( ) ) , verbose) {
0 commit comments