@@ -8,27 +8,37 @@ use strum::IntoEnumIterator;
8
8
9
9
pub mod language;
10
10
11
- pub fn get_dominant_language ( languages_stat_vec : & [ ( Language , f64 ) ] ) -> Language {
12
- languages_stat_vec [ 0 ] . 0
11
+ pub fn get_main_language ( loc_by_language : & [ ( Language , usize ) ] ) -> Language {
12
+ loc_by_language [ 0 ] . 0
13
13
}
14
14
15
- pub fn get_language_statistics (
15
+ /// Returns a vector of tuples containing all the languages detected inside the repository.
16
+ /// Each tuple is composed of the language and its corresponding loc (lines of code).
17
+ /// The vector is sorted by loc in descending order.
18
+ pub fn get_loc_by_language_sorted (
16
19
dir : & Path ,
17
20
ignored_directories : & [ PathBuf ] ,
18
21
language_types : & [ LanguageType ] ,
19
22
include_hidden : bool ,
20
- ) -> Result < ( Vec < ( Language , f64 ) > , usize ) > {
23
+ ) -> Result < Vec < ( Language , usize ) > > {
21
24
let stats = get_statistics ( dir, ignored_directories, language_types, include_hidden) ;
22
- let language_distribution = get_language_distribution ( & stats)
23
- . context ( "Could not find any source code in this repository" ) ?;
24
- let mut language_distribution_vec: Vec < ( _ , _ ) > = language_distribution. into_iter ( ) . collect ( ) ;
25
- language_distribution_vec. sort_by ( |a, b| a. 1 . partial_cmp ( & b. 1 ) . unwrap ( ) . reverse ( ) ) ;
26
- let loc = get_total_loc ( & stats) ;
27
- Ok ( ( language_distribution_vec, loc) )
25
+
26
+ let loc_by_language =
27
+ get_loc_by_language ( & stats) . context ( "Could not find any source code in this repository" ) ?;
28
+
29
+ let loc_by_language_sorted = sort_by_loc ( loc_by_language) ;
30
+
31
+ Ok ( loc_by_language_sorted)
32
+ }
33
+
34
+ fn sort_by_loc ( map : HashMap < Language , usize > ) -> Vec < ( Language , usize ) > {
35
+ let mut vec: Vec < ( Language , usize ) > = map. into_iter ( ) . collect ( ) ;
36
+ vec. sort_by ( |a, b| b. 1 . cmp ( & a. 1 ) ) ;
37
+ vec
28
38
}
29
39
30
- fn get_language_distribution ( languages : & tokei:: Languages ) -> Option < HashMap < Language , f64 > > {
31
- let mut language_distribution = HashMap :: new ( ) ;
40
+ fn get_loc_by_language ( languages : & tokei:: Languages ) -> Option < HashMap < Language , usize > > {
41
+ let mut loc_by_language = HashMap :: new ( ) ;
32
42
33
43
for ( language_name, language) in languages. iter ( ) {
34
44
let loc = language:: loc ( language_name, language) ;
@@ -37,27 +47,20 @@ fn get_language_distribution(languages: &tokei::Languages) -> Option<HashMap<Lan
37
47
continue ;
38
48
}
39
49
40
- language_distribution . insert ( Language :: from ( * language_name) , loc as f64 ) ;
50
+ loc_by_language . insert ( Language :: from ( * language_name) , loc) ;
41
51
}
42
52
43
- let total: f64 = language_distribution. values ( ) . sum ( ) ;
44
-
45
- if total. abs ( ) < f64:: EPSILON {
53
+ let total_loc: usize = loc_by_language. values ( ) . sum ( ) ;
54
+ if total_loc == 0 {
46
55
None
47
56
} else {
48
- for ( _, val) in language_distribution. iter_mut ( ) {
49
- * val /= total;
50
- * val *= 100_f64 ;
51
- }
52
-
53
- Some ( language_distribution)
57
+ Some ( loc_by_language)
54
58
}
55
59
}
56
60
57
- fn get_total_loc ( languages : & tokei:: Languages ) -> usize {
58
- languages. iter ( ) . fold ( 0 , |sum, ( lang_type, lang) | {
59
- sum + language:: loc ( lang_type, lang)
60
- } )
61
+ pub fn get_total_loc ( loc_by_language : & [ ( Language , usize ) ] ) -> usize {
62
+ let total_loc: usize = loc_by_language. iter ( ) . map ( |( _, v) | v) . sum ( ) ;
63
+ total_loc
61
64
}
62
65
63
66
fn get_statistics (
@@ -110,7 +113,7 @@ mod test {
110
113
use tokei;
111
114
112
115
#[ test]
113
- fn get_language_distribution_counts_md_comments ( ) {
116
+ fn get_loc_by_language_counts_md_comments ( ) {
114
117
let js = tokei:: Language {
115
118
blanks : 25 ,
116
119
comments : 50 ,
@@ -131,36 +134,11 @@ mod test {
131
134
languages. insert ( js_type, js) ;
132
135
languages. insert ( md_type, md) ;
133
136
134
- let language_distribution = get_language_distribution ( & languages) . unwrap ( ) ;
135
-
136
- // NOTE: JS is 25% with 100 lines of code, MD is 75% with 300 lines of code + comments
137
- assert_eq ! ( language_distribution[ & Language :: JavaScript ] , 25_f64 ) ;
138
- assert_eq ! ( language_distribution[ & Language :: Markdown ] , 75_f64 ) ;
139
- }
140
-
141
- #[ test]
142
- fn get_total_loc_counts_md_comments ( ) {
143
- let js = tokei:: Language {
144
- blanks : 25 ,
145
- comments : 50 ,
146
- code : 100 ,
147
- ..Default :: default ( )
148
- } ;
149
- let js_type = tokei:: LanguageType :: JavaScript ;
150
-
151
- let md = tokei:: Language {
152
- blanks : 50 ,
153
- comments : 200 ,
154
- code : 100 ,
155
- ..Default :: default ( )
156
- } ;
157
- let md_type = tokei:: LanguageType :: Markdown ;
137
+ let loc_by_language = get_loc_by_language ( & languages) . unwrap ( ) ;
158
138
159
- let mut languages = tokei:: Languages :: new ( ) ;
160
- languages. insert ( js_type, js) ;
161
- languages. insert ( md_type, md) ;
162
-
163
- assert_eq ! ( get_total_loc( & languages) , 400 ) ;
139
+ // NOTE: JS with 100 lines of code, MD with 300 lines of code + comments
140
+ assert_eq ! ( loc_by_language[ & Language :: JavaScript ] , 100 ) ;
141
+ assert_eq ! ( loc_by_language[ & Language :: Markdown ] , 300 ) ;
164
142
}
165
143
166
144
#[ test]
@@ -190,6 +168,35 @@ mod test {
190
168
let mut languages = tokei:: Languages :: new ( ) ;
191
169
languages. insert ( tokei:: LanguageType :: Jupyter , jupyter_notebook) ;
192
170
193
- assert_eq ! ( get_total_loc( & languages) , 21 ) ;
171
+ let loc_by_language = get_loc_by_language ( & languages) . unwrap ( ) ;
172
+
173
+ assert_eq ! ( loc_by_language[ & Language :: Jupyter ] , 21 ) ;
174
+ }
175
+
176
+ #[ test]
177
+ fn test_get_loc_by_language_sorted ( ) {
178
+ let mut map = HashMap :: new ( ) ;
179
+ map. insert ( Language :: Ada , 300 ) ;
180
+ map. insert ( Language :: Java , 40 ) ;
181
+ map. insert ( Language :: Rust , 1200 ) ;
182
+ map. insert ( Language :: Go , 8 ) ;
183
+
184
+ let sorted_map = sort_by_loc ( map) ;
185
+
186
+ let expected_order = vec ! [
187
+ ( Language :: Rust , 1200 ) ,
188
+ ( Language :: Ada , 300 ) ,
189
+ ( Language :: Java , 40 ) ,
190
+ ( Language :: Go , 8 ) ,
191
+ ] ;
192
+ let actual_order: Vec < _ > = sorted_map. into_iter ( ) . collect ( ) ;
193
+
194
+ assert_eq ! ( expected_order, actual_order) ;
195
+ }
196
+
197
+ #[ test]
198
+ fn test_get_total_loc ( ) {
199
+ let loc_by_language = [ ( Language :: JavaScript , 100 ) , ( Language :: Markdown , 300 ) ] ;
200
+ assert_eq ! ( get_total_loc( & loc_by_language) , 400 ) ;
194
201
}
195
202
}
0 commit comments