Build the stats rows (files/nodes/edges, DB size, languages).
(stats: &GraphStats, num_cols: usize)
| 400 | |
| 401 | /// Build the stats rows (files/nodes/edges, DB size, languages). |
| 402 | fn build_stats_rows(stats: &GraphStats, num_cols: usize) -> Vec<Vec<(&str, String)>> { |
| 403 | let mut sorted_langs: Vec<_> = stats.files_by_language.iter().collect(); |
| 404 | sorted_langs.sort_by(|a, b| b.1.cmp(a.1)); |
| 405 | |
| 406 | let mut rows: Vec<Vec<(&str, String)>> = vec![vec![ |
| 407 | ("Files", format_number(stats.file_count)), |
| 408 | ("Nodes", format_number(stats.node_count)), |
| 409 | ("Edges", format_number(stats.edge_count)), |
| 410 | ]]; |
| 411 | |
| 412 | let mut second_row: Vec<(&str, String)> = vec![("DB Size", format_bytes(stats.db_size_bytes))]; |
| 413 | if stats.total_source_bytes > 0 { |
| 414 | second_row.push(("Source", format_bytes(stats.total_source_bytes))); |
| 415 | } |
| 416 | let mut lang_idx = 0; |
| 417 | while second_row.len() < num_cols && lang_idx < sorted_langs.len() { |
| 418 | let (lang, count) = sorted_langs[lang_idx]; |
| 419 | second_row.push((lang.as_str(), format_number(*count))); |
| 420 | lang_idx += 1; |
| 421 | } |
| 422 | while second_row.len() < num_cols { |
| 423 | second_row.push(("", String::new())); |
| 424 | } |
| 425 | rows.push(second_row); |
| 426 | |
| 427 | while lang_idx < sorted_langs.len() { |
| 428 | let mut row: Vec<(&str, String)> = Vec::new(); |
| 429 | for _ in 0..num_cols { |
| 430 | if lang_idx < sorted_langs.len() { |
| 431 | let (lang, count) = sorted_langs[lang_idx]; |
| 432 | row.push((lang.as_str(), format_number(*count))); |
| 433 | lang_idx += 1; |
| 434 | } else { |
| 435 | row.push(("", String::new())); |
| 436 | } |
| 437 | } |
| 438 | rows.push(row); |
| 439 | } |
| 440 | rows |
| 441 | } |
| 442 | |
| 443 | /// Print rows of label-value pairs in a bordered table. |
| 444 | fn print_table_rows(rows: &[Vec<(&str, String)>], cell_width: usize, num_cols: usize) { |
no test coverage detected