@@ -19,11 +19,7 @@ use ra_ap_syntax::{
1919 ast:: { self , HasDocComments , HasGenericParams , HasName } ,
2020 AstNode , SourceFile , SyntaxKind ,
2121} ;
22- use rayon:: {
23- prelude:: { IndexedParallelIterator , IntoParallelRefIterator , ParallelExtend , ParallelIterator } ,
24- slice:: ParallelSliceMut ,
25- str:: ParallelString ,
26- } ;
22+ use rayon:: prelude:: { IntoParallelRefIterator , ParallelIterator } ;
2723
2824use std:: { collections:: HashMap , error:: Error , process:: Command } ;
2925pub use types:: {
@@ -108,9 +104,9 @@ pub enum Filter {
108104// TODO: split this function into smaller functions
109105pub fn get_function_history (
110106 name : & str ,
111- file : FileType ,
107+ file : & FileType ,
112108 filter : Filter ,
113- ) -> Result < FunctionHistory , Box < dyn Error > > {
109+ ) -> Result < FunctionHistory , Box < dyn Error + Send + Sync > > {
114110 // chack if name is empty
115111 if name. is_empty ( ) {
116112 Err ( "function name is empty" ) ?;
@@ -162,60 +158,54 @@ pub fn get_function_history(
162158 }
163159 let stdout = String :: from_utf8 ( output. stdout ) ?;
164160 let commits = stdout
165- . par_lines ( )
161+ . lines ( )
166162 . map ( |line| {
167163 let mut parts = line. split ( ';' ) ;
168- let id = parts. next ( ) . expect ( "no id found in git command output" ) ;
164+ let id = parts
165+ . next ( )
166+ . unwrap_to_error ( "no id found in git command output" ) ;
169167 let date = parts
170168 . next ( )
171- . expect ( "date is missing from git command output" ) ;
169+ . unwrap_to_error ( "date is missing from git command output" ) ;
172170 let author = parts
173171 . next ( )
174- . expect ( "author is missing from git command output" ) ;
172+ . unwrap_to_error ( "author is missing from git command output" ) ;
175173 let email = parts
176174 . next ( )
177- . expect ( "email is missing from git command output" ) ;
175+ . unwrap_to_error ( "email is missing from git command output" ) ;
178176 let message = parts
179177 . next ( )
180- . expect ( "message is missing from git command output" ) ;
181- ( id , date, author, email, message)
178+ . unwrap_to_error ( "message is missing from git command output" ) ;
179+ Ok ( ( id? , date? , author? , email? , message? ) )
182180 } )
183- . collect :: < Vec < _ > > ( ) ;
181+ . collect :: < Result < Vec < _ > , Box < dyn Error + Send + Sync > > > ( ) ?;
182+
184183 let mut file_history = FunctionHistory :: new ( String :: from ( name) , Vec :: new ( ) ) ;
185184 let err = "no history found" . to_string ( ) ;
186- match file {
187- FileType :: Absolute ( path) => {
188- if !path. ends_with ( ".rs" ) {
189- return Err ( "not a rust file" ) ?;
190- }
191- file_history
192- . commit_history
193- . par_extend ( commits. par_iter ( ) . filter_map ( move |commit| {
194- match find_function_in_commit ( commit. 0 , & path, name) {
195- Ok ( contents) => {
196- // file_history.commit_history.push(
197- Some ( CommitFunctions :: new (
198- commit. 0 . to_string ( ) ,
199- vec ! [ File :: new( path. to_string( ) , contents) ] ,
200- commit. 1 ,
201- commit. 2 . to_string ( ) ,
202- commit. 3 . to_string ( ) ,
203- commit. 4 . to_string ( ) ,
204- ) )
205- }
206- Err ( _) => None ,
207- }
208- } ) ) ;
185+ // check if file is a rust file
186+ if let FileType :: Absolute ( path) | FileType :: Relative ( path) = & file {
187+ if !path. ends_with ( ".rs" ) {
188+ Err ( "file is not a rust file" ) ?;
209189 }
190+ }
191+ file_history. commit_history = commits
192+ . par_iter ( )
193+ . filter_map ( |commit| {
194+ match & file {
195+ FileType :: Absolute ( path) => match find_function_in_commit ( commit. 0 , path, name) {
196+ Ok ( contents) => Some ( CommitFunctions :: new (
197+ commit. 0 . to_string ( ) ,
198+ vec ! [ File :: new( path. to_string( ) , contents) ] ,
199+ commit. 1 ,
200+ commit. 2 . to_string ( ) ,
201+ commit. 3 . to_string ( ) ,
202+ commit. 4 . to_string ( ) ,
203+ ) ) ,
204+ Err ( _) => None ,
205+ } ,
210206
211- FileType :: Relative ( ref path) => {
212- if !path. ends_with ( ".rs" ) {
213- return Err ( "not a rust file" ) ?;
214- }
215- file_history
216- . commit_history
217- . par_extend ( commits. par_iter ( ) . filter_map ( |commit| {
218- match find_function_in_commit_with_filetype ( commit. 0 , name, & file) {
207+ FileType :: Relative ( _) => {
208+ match find_function_in_commit_with_filetype ( commit. 0 , name, file) {
219209 Ok ( contents) => Some ( CommitFunctions :: new (
220210 commit. 0 . to_string ( ) ,
221211 contents,
@@ -229,13 +219,10 @@ pub fn get_function_history(
229219 None
230220 }
231221 }
232- } ) ) ;
233- }
222+ }
234223
235- FileType :: None | FileType :: Directory ( _) => {
236- file_history. commit_history . par_extend (
237- commits. par_iter ( ) . filter_map (
238- |commit| match find_function_in_commit_with_filetype ( commit. 0 , name, & file) {
224+ FileType :: None | FileType :: Directory ( _) => {
225+ match find_function_in_commit_with_filetype ( commit. 0 , name, file) {
239226 Ok ( contents) => Some ( CommitFunctions :: new (
240227 commit. 0 . to_string ( ) ,
241228 contents,
@@ -245,11 +232,11 @@ pub fn get_function_history(
245232 commit. 4 . to_string ( ) ,
246233 ) ) ,
247234 Err ( _) => None ,
248- } ,
249- ) , // .collect::<Vec<_>>(),
250- ) ;
251- }
252- }
235+ }
236+ }
237+ }
238+ } )
239+ . collect ( ) ;
253240 if file_history. commit_history . is_empty ( ) {
254241 return Err ( err) ?;
255242 }
@@ -305,10 +292,9 @@ fn find_function_in_commit(
305292 . map ( |x| x. 0 )
306293 . collect :: < Vec < _ > > ( ) ;
307294 starts. push ( 0 ) ;
308- // starts.sort_unstable();
309- starts. par_sort ( ) ;
295+ starts. sort_unstable ( ) ;
310296 let map = starts
311- . par_iter ( )
297+ . iter ( )
312298 . enumerate ( )
313299 . collect :: < HashMap < usize , & usize > > ( ) ;
314300 let mut hist = Vec :: new ( ) ;
@@ -506,7 +492,7 @@ fn get_stuff<T: AstNode>(
506492 "\n {}: {}" ,
507493 end_line,
508494 file. lines( )
509- . nth( if end_line == file. par_lines ( ) . count( ) - 1 {
495+ . nth( if end_line == file. lines ( ) . count( ) - 1 {
510496 end_line
511497 } else {
512498 end_line - 1
@@ -580,25 +566,25 @@ fn find_function_in_commit_with_filetype(
580566 }
581567 }
582568 let err = "no function found" . to_string ( ) ;
583- let mut returns = Vec :: new ( ) ;
584- returns . par_extend ( files . par_iter ( ) . filter_map ( |file| {
585- match find_function_in_commit ( commit, file, name) {
569+ let returns: Vec < File > = files
570+ . par_iter ( )
571+ . filter_map ( |file| match find_function_in_commit ( commit, file, name) {
586572 Ok ( functions) => Some ( File :: new ( ( * file) . to_string ( ) , functions) ) ,
587573 Err ( _) => None ,
588- }
589- } ) ) ;
574+ } )
575+ . collect ( ) ;
590576 if returns. is_empty ( ) {
591577 Err ( err) ?;
592578 }
593579 Ok ( returns)
594580}
595581
596582trait UwrapToError < T > {
597- fn unwrap_to_error ( self , message : & str ) -> Result < T , Box < dyn Error > > ;
583+ fn unwrap_to_error ( self , message : & str ) -> Result < T , Box < dyn Error + Send + Sync > > ;
598584}
599585
600586impl < T > UwrapToError < T > for Option < T > {
601- fn unwrap_to_error ( self , message : & str ) -> Result < T , Box < dyn Error > > {
587+ fn unwrap_to_error ( self , message : & str ) -> Result < T , Box < dyn Error + Send + Sync > > {
602588 match self {
603589 Some ( val) => Ok ( val) ,
604590 None => Err ( message. to_string ( ) . into ( ) ) ,
@@ -616,7 +602,7 @@ mod tests {
616602 let now = Utc :: now ( ) ;
617603 let output = get_function_history (
618604 "empty_test" ,
619- FileType :: Relative ( "src/test_functions.rs" . to_string ( ) ) ,
605+ & FileType :: Relative ( "src/test_functions.rs" . to_string ( ) ) ,
620606 Filter :: None ,
621607 ) ;
622608 let after = Utc :: now ( ) - now;
@@ -633,7 +619,7 @@ mod tests {
633619 fn git_installed ( ) {
634620 let output = get_function_history (
635621 "empty_test" ,
636- FileType :: Absolute ( "src/test_functions.rs" . to_string ( ) ) ,
622+ & FileType :: Absolute ( "src/test_functions.rs" . to_string ( ) ) ,
637623 Filter :: None ,
638624 ) ;
639625 // assert that err is "not git is not installed"
@@ -646,7 +632,7 @@ mod tests {
646632 fn not_found ( ) {
647633 let output = get_function_history (
648634 "Not_a_function" ,
649- FileType :: Absolute ( "src/test_functions.rs" . to_string ( ) ) ,
635+ & FileType :: Absolute ( "src/test_functions.rs" . to_string ( ) ) ,
650636 Filter :: None ,
651637 ) ;
652638 match & output {
@@ -660,18 +646,18 @@ mod tests {
660646 fn not_rust_file ( ) {
661647 let output = get_function_history (
662648 "empty_test" ,
663- FileType :: Absolute ( "src/test_functions.txt" . to_string ( ) ) ,
649+ & FileType :: Absolute ( "src/test_functions.txt" . to_string ( ) ) ,
664650 Filter :: None ,
665651 ) ;
666652 assert ! ( output. is_err( ) ) ;
667- assert_eq ! ( output. unwrap_err( ) . to_string( ) , "not a rust file" ) ;
653+ assert_eq ! ( output. unwrap_err( ) . to_string( ) , "file is not a rust file" ) ;
668654 }
669655 #[ test]
670656 fn test_date ( ) {
671657 let now = Utc :: now ( ) ;
672658 let output = get_function_history (
673659 "empty_test" ,
674- FileType :: None ,
660+ & FileType :: None ,
675661 Filter :: DateRange (
676662 "17 Aug 2022 11:27:23 -0400" . to_owned ( ) ,
677663 "19 Aug 2022 23:45:52 +0000" . to_owned ( ) ,
@@ -691,7 +677,7 @@ mod tests {
691677 #[ test]
692678 fn expensive_tes ( ) {
693679 let now = Utc :: now ( ) ;
694- let output = get_function_history ( "empty_test" , FileType :: None , Filter :: None ) ;
680+ let output = get_function_history ( "empty_test" , & FileType :: None , Filter :: None ) ;
695681 let after = Utc :: now ( ) - now;
696682 println ! ( "time taken: {}" , after. num_seconds( ) ) ;
697683 match & output {
0 commit comments