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 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 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}