rsv_lib/csv/
count.rs

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        // current file
12        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    // progress
23    let mut prog = Progress::new();
24
25    // open file and count
26    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}