11use serde:: { Deserialize , Serialize } ;
22use std:: fs:: { self , File } ;
33use std:: path:: { Path , PathBuf } ;
4- use std:: io:: { self , Write } ;
54use std:: process:: { Command , exit} ;
65use std:: time:: Instant ;
6+ use std:: io:: { self , Write } ;
77
88#[ derive( Serialize , Deserialize , Debug , Clone ) ]
99struct Exercise {
1010 name : String ,
1111 path : String ,
1212 #[ serde( rename = "type" ) ]
1313 exercise_type : String ,
14- score : i32 ,
14+ score : i32 , // Added: Each exercise score
1515}
1616
1717#[ derive( Serialize , Deserialize , Debug ) ]
@@ -25,15 +25,15 @@ struct ExerciseConfig {
2525struct ExerciseResult {
2626 name : String ,
2727 result : bool ,
28- score : i32 ,
28+ score : i32 , // Store score for each exercise
2929}
3030
3131#[ derive( Serialize , Deserialize , Debug ) ]
3232struct Statistics {
3333 total_exercises : usize ,
3434 total_successes : usize ,
3535 total_failures : usize ,
36- total_score : i32 ,
36+ total_score : i32 , // Total score for the assessment
3737 total_time : u64 ,
3838}
3939
@@ -43,7 +43,6 @@ struct Report {
4343 statistics : Statistics ,
4444}
4545
46-
4746fn main ( ) {
4847 let args: Vec < String > = std:: env:: args ( ) . collect ( ) ;
4948 if args. len ( ) < 2 {
@@ -54,7 +53,7 @@ fn main() {
5453 let mode = & args[ 1 ] ;
5554 let start_time = Instant :: now ( ) ;
5655
57- // 加载 JSON 配置
56+ // Load the exercise config
5857 let config = match load_exercise_config ( "exercise_config.json" ) {
5958 Ok ( cfg) => cfg,
6059 Err ( e) => {
@@ -69,49 +68,50 @@ fn main() {
6968 total_exercises : 0 ,
7069 total_successes : 0 ,
7170 total_failures : 0 ,
72- total_score : 0 ,
71+ total_score : 0 , // Initialize total score to 0
7372 total_time : 0 ,
7473 } ,
7574 } ;
7675
77-
76+ // Evaluate exercises from config
7877 evaluate_exercises_from_config ( mode, config, & mut report) ;
7978
80-
79+ // Calculate total time
8180 report. statistics . total_time = start_time. elapsed ( ) . as_secs ( ) ;
8281 report. statistics . total_exercises = report. statistics . total_successes + report. statistics . total_failures ;
8382
84-
83+ // Output summary
8584 println ! ( "\n Summary:" ) ;
8685 println ! ( "Total exercises: {}" , report. statistics. total_exercises) ;
8786 println ! ( "Total successes: {}" , report. statistics. total_successes) ;
8887 println ! ( "Total failures: {}" , report. statistics. total_failures) ;
89- println ! ( "Total score: {}" , report. statistics. total_score) ;
88+ println ! ( "Total score: {}" , report. statistics. total_score) ; // Output the total score
9089
91-
90+ // Save the report to a JSON file
9291 if let Err ( e) = save_report_to_json ( "report.json" , & report) {
9392 eprintln ! ( "Error saving report: {}" , e) ;
9493 }
9594}
9695
97-
96+ // Load exercise configuration from JSON
9897fn load_exercise_config ( file_path : & str ) -> Result < ExerciseConfig , io:: Error > {
9998 let file = File :: open ( file_path) ?;
10099 let config: ExerciseConfig = serde_json:: from_reader ( file) ?;
101100 Ok ( config)
102101}
103102
104-
103+ // Evaluate all exercises from the configuration
105104fn evaluate_exercises_from_config ( mode : & str , config : ExerciseConfig , report : & mut Report ) {
106105 let all_exercises = [ config. easy , config. normal , config. hard ] . concat ( ) ;
107106
108107 for exercise in all_exercises {
109108 println ! ( "\n Evaluating {}: {}" , exercise. exercise_type, exercise. name) ;
110109 let result = evaluate_exercise ( & exercise) ;
111110
112-
111+ // Calculate score based on result
113112 let score = if result { exercise. score } else { 0 } ;
114113
114+ // Add result to the report
115115 report. exercises . push ( ExerciseResult {
116116 name : exercise. name . clone ( ) ,
117117 result,
@@ -124,7 +124,7 @@ fn evaluate_exercises_from_config(mode: &str, config: ExerciseConfig, report: &m
124124 report. statistics . total_failures += 1 ;
125125 }
126126
127-
127+ // Add score to total score
128128 report. statistics . total_score += score;
129129
130130 if mode == "watch" && !ask_to_continue ( ) {
@@ -133,7 +133,7 @@ fn evaluate_exercises_from_config(mode: &str, config: ExerciseConfig, report: &m
133133 }
134134}
135135
136-
136+ // Evaluate a single exercise
137137fn evaluate_exercise ( exercise : & Exercise ) -> bool {
138138 let exercise_path = PathBuf :: from ( & format ! ( "./exercises/{}" , exercise. path) ) ;
139139 match exercise. exercise_type . as_str ( ) {
@@ -146,7 +146,7 @@ fn evaluate_exercise(exercise: &Exercise) -> bool {
146146 }
147147}
148148
149-
149+ // Evaluate a single file Rust exercise
150150fn evaluate_single_file ( file_path : & PathBuf ) -> bool {
151151 let output = Command :: new ( "rustc" )
152152 . arg ( file_path)
@@ -169,7 +169,7 @@ fn evaluate_single_file(file_path: &PathBuf) -> bool {
169169 }
170170}
171171
172-
172+ // Evaluate a cargo project
173173fn evaluate_cargo_project ( proj_path : & PathBuf ) -> bool {
174174 let build_success = run_cargo_command ( proj_path, "build" ) ;
175175 let test_success = run_cargo_command ( proj_path, "test" ) ;
@@ -183,10 +183,13 @@ fn evaluate_cargo_project(proj_path: &PathBuf) -> bool {
183183 println ! ( "\x1b [31m{}: FAILED\x1b [0m" , proj_path. display( ) ) ;
184184 }
185185
186+ // Clean up the target directory after evaluation
187+ clean_target_directory ( proj_path) ;
188+
186189 passed
187190}
188191
189-
192+ // Run a cargo command (build, test, clippy)
190193fn run_cargo_command ( proj_path : & PathBuf , command : & str ) -> bool {
191194 let output = Command :: new ( "cargo" )
192195 . arg ( command)
@@ -199,15 +202,28 @@ fn run_cargo_command(proj_path: &PathBuf, command: &str) -> bool {
199202 }
200203}
201204
205+ // Clean up the target directory after evaluating a cargo project
206+ fn clean_target_directory ( proj_path : & PathBuf ) {
207+ let target_dir = proj_path. join ( "target" ) ;
208+
209+ if target_dir. exists ( ) {
210+ if let Err ( e) = fs:: remove_dir_all ( & target_dir) {
211+ eprintln ! ( "Failed to clean up target directory: {}" , e) ;
212+ } else {
213+ println ! ( "Successfully cleaned up target directory in: {}" , proj_path. display( ) ) ;
214+ }
215+ }
216+ }
202217
218+ // Ask the user whether to continue after each evaluation
203219fn ask_to_continue ( ) -> bool {
204220 let mut input = String :: new ( ) ;
205221 println ! ( "\n Press any key to continue, or 'q' to quit." ) ;
206222 io:: stdin ( ) . read_line ( & mut input) . unwrap ( ) ;
207223 input. trim ( ) . to_lowercase ( ) != "q"
208224}
209225
210-
226+ // Save the report to a JSON file
211227fn save_report_to_json ( file_name : & str , report : & Report ) -> io:: Result < ( ) > {
212228 let file = File :: create ( file_name) ?;
213229 serde_json:: to_writer_pretty ( file, report) ?;
0 commit comments