rsv_lib/csv_lib/
count.rs

1use crate::args::Count;
2use crate::utils::return_result::{CliResultData, ResultData};
3use std::fs::File;
4use std::io::{BufRead, BufReader};
5use std::path::Path;
6extern crate bytecount;
7
8impl Count {
9    #[allow(dead_code)]
10    pub fn csv_run_lib(&self) -> CliResultData {
11        let mut out = ResultData::new();
12
13        // current file
14        let n = match self.path().is_dir() {
15            true => count_dir_files(&self.path())?,
16            false => count_file_lines(&self.path(), self.no_header)?,
17        };
18
19        out.insert_header(vec!["count".to_string()]);
20        out.insert_record(vec![n.to_string()]);
21
22        Ok(Some(out))
23    }
24}
25
26#[allow(dead_code)]
27fn count_file_lines(path: &Path, no_header: bool) -> Result<usize, Box<dyn std::error::Error>> {
28    // open file and count
29    let mut n = 0;
30    let file = File::open(path)?;
31    let mut rdr = BufReader::with_capacity(1024 * 32, file);
32    loop {
33        let bytes_read = {
34            let buf = rdr.fill_buf()?;
35            if buf.is_empty() {
36                break;
37            }
38            n += bytecount::count(buf, b'\n');
39            buf.len()
40        };
41
42        rdr.consume(bytes_read);
43    }
44
45    if !no_header && n > 0 {
46        n -= 1;
47    }
48
49    Ok(n)
50}
51
52#[allow(dead_code)]
53fn count_dir_files(path: &Path) -> Result<usize, Box<dyn std::error::Error>> {
54    let mut file_n = 0;
55    let mut dir_n = 0;
56
57    path.read_dir()?.for_each(|i| {
58        if let Ok(e) = i {
59            if e.file_type().unwrap().is_file() {
60                file_n += 1;
61            } else {
62                dir_n += 1;
63            }
64        }
65    });
66
67    Ok(file_n)
68}