1use crate::args::Count;
2use crate::utils::cli_result::CliResult;
3use crate::utils::progress::Progress;
4use std::fs::File;
5use std::io::{BufRead, BufReader};
6use std::path::Path;
7extern crate bytecount;
8
9impl Count {
10 pub fn csv_run(&self) -> CliResult {
11 match self.path().is_dir() {
13 true => count_dir_files(&self.path())?,
14 false => count_file_lines(&self.path(), self.no_header)?,
15 };
16
17 Ok(())
18 }
19}
20
21fn count_file_lines(path: &Path, no_header: bool) -> CliResult {
22 let mut prog = Progress::new();
24
25 let mut n = 0;
27 let file = File::open(path)?;
28 let mut rdr = BufReader::with_capacity(1024 * 32, file);
29 loop {
30 let bytes_read = {
31 let buf = rdr.fill_buf()?;
32 if buf.is_empty() {
33 break;
34 }
35 n += bytecount::count(buf, b'\n');
36 buf.len()
37 };
38
39 rdr.consume(bytes_read);
40 }
41
42 if !no_header && n > 0 {
43 n -= 1;
44 }
45
46 println!("{n}");
47 prog.print_elapsed_time();
48
49 Ok(())
50}
51
52fn count_dir_files(path: &Path) -> CliResult {
53 let mut file_n = 0;
54 let mut dir_n = 0;
55
56 path.read_dir()?.for_each(|i| {
57 if let Ok(e) = i {
58 if e.file_type().unwrap().is_file() {
59 file_n += 1;
60 } else {
61 dir_n += 1;
62 }
63 }
64 });
65
66 println!(
67 "{} files and {} sub-directories in {}",
68 file_n,
69 dir_n,
70 path.display()
71 );
72
73 Ok(())
74}