@@ -14,7 +14,8 @@ extern crate log;
1414use clap:: { App , Arg } ;
1515
1616use rustpython_parser:: { ast, parser} ;
17- use std:: path:: Path ;
17+ use std:: path:: { Path , PathBuf } ;
18+ use std:: time:: Instant ;
1819
1920fn main ( ) {
2021 env_logger:: init ( ) ;
@@ -32,14 +33,21 @@ fn main() {
3233 let folder = Path :: new ( matches. value_of ( "folder" ) . unwrap ( ) ) ;
3334 if folder. exists ( ) && folder. is_dir ( ) {
3435 println ! ( "Parsing folder of python code: {:?}" , folder) ;
35- let res = parse_folder ( & folder) . unwrap ( ) ;
36- println ! ( "Processed {:?} files" , res. len( ) ) ;
36+ let t1 = Instant :: now ( ) ;
37+ let parsed_files = parse_folder ( & folder) . unwrap ( ) ;
38+ let t2 = Instant :: now ( ) ;
39+ let results = ScanResult {
40+ t1,
41+ t2,
42+ parsed_files,
43+ } ;
44+ statistics ( results) ;
3745 } else {
3846 println ! ( "{:?} is not a folder." , folder) ;
3947 }
4048}
4149
42- fn parse_folder ( path : & Path ) -> std:: io:: Result < Vec < ast :: Program > > {
50+ fn parse_folder ( path : & Path ) -> std:: io:: Result < Vec < ParsedFile > > {
4351 let mut res = vec ! [ ] ;
4452 info ! ( "Parsing folder of python code: {:?}" , path) ;
4553 for entry in path. read_dir ( ) ? {
@@ -49,22 +57,66 @@ fn parse_folder(path: &Path) -> std::io::Result<Vec<ast::Program>> {
4957
5058 let path = entry. path ( ) ;
5159 if metadata. is_dir ( ) {
52- let x = parse_folder ( & path) ?;
53- res. extend ( x) ;
60+ res. extend ( parse_folder ( & path) ?) ;
5461 }
5562
5663 if metadata. is_file ( ) && path. extension ( ) . and_then ( |s| s. to_str ( ) ) == Some ( "py" ) {
57- match parse_python_file ( & path) {
58- Ok ( x) => res. push ( x) ,
64+ let result = parse_python_file ( & path) ;
65+ match & result {
66+ Ok ( _) => { }
5967 Err ( y) => error ! ( "Erreur in file {:?} {:?}" , path, y) ,
6068 }
69+ res. push ( ParsedFile {
70+ filename : Box :: new ( path) ,
71+ result,
72+ } ) ;
6173 }
6274 }
6375 Ok ( res)
6476}
6577
66- fn parse_python_file ( filename : & Path ) -> Result < ast :: Program , String > {
78+ fn parse_python_file ( filename : & Path ) -> ParseResult {
6779 info ! ( "Parsing file {:?}" , filename) ;
6880 let source = std:: fs:: read_to_string ( filename) . map_err ( |e| e. to_string ( ) ) ?;
6981 parser:: parse_program ( & source) . map_err ( |e| e. to_string ( ) )
7082}
83+
84+ fn statistics ( results : ScanResult ) {
85+ // println!("Processed {:?} files", res.len());
86+ println ! ( "Scanned a total of {} files" , results. parsed_files. len( ) ) ;
87+ let total = results. parsed_files . len ( ) ;
88+ let failed = results
89+ . parsed_files
90+ . iter ( )
91+ . filter ( |p| p. result . is_err ( ) )
92+ . count ( ) ;
93+ let passed = results
94+ . parsed_files
95+ . iter ( )
96+ . filter ( |p| p. result . is_ok ( ) )
97+ . count ( ) ;
98+ println ! ( "Passed: {} Failed: {} Total: {}" , passed, failed, total) ;
99+ println ! (
100+ "That is {} % success rate." ,
101+ ( passed as f64 * 100.0 ) / total as f64
102+ ) ;
103+ let duration = results. t2 - results. t1 ;
104+ println ! ( "Total time spend: {:?}" , duration) ;
105+ println ! (
106+ "File processing rate: {} files/second" ,
107+ ( total * 1_000_000 ) as f64 / duration. as_micros( ) as f64
108+ ) ;
109+ }
110+
111+ struct ScanResult {
112+ t1 : Instant ,
113+ t2 : Instant ,
114+ parsed_files : Vec < ParsedFile > ,
115+ }
116+
117+ struct ParsedFile {
118+ filename : Box < PathBuf > ,
119+ result : ParseResult ,
120+ }
121+
122+ type ParseResult = Result < ast:: Program , String > ;
0 commit comments