1use crate::args::Tail;
2use crate::utils::cli_result::CliResult;
3use crate::utils::filename::new_path;
4use crate::utils::writer::Writer;
5use std::collections::VecDeque;
6use std::fs::File;
7use std::io::{BufRead, BufReader};
8
9impl Tail {
10 pub fn csv_run(&self) -> CliResult {
11 let path = &self.path();
12 let n = if self.n == 0 { usize::MAX - 10 } else { self.n };
13 let out = new_path(path, "-tail");
14 let mut rdr = BufReader::new(File::open(path)?);
15 let mut wtr = Writer::file_or_stdout(self.export, &out)?;
16
17 let mut lines = VecDeque::new();
19
20 let mut buf = vec![];
22 if !self.no_header {
23 rdr.read_until(b'\n', &mut buf)?;
24 wtr.write_bytes_unchecked(&buf);
25 };
26 buf.clear();
27
28 while let Ok(nread) = rdr.read_until(b'\n', &mut buf) {
30 if nread == 0 {
31 break;
32 }
33 if lines.len() >= n {
34 lines.pop_front();
35 }
36 lines.push_back(buf[..nread].to_owned());
37 buf.clear();
38 }
39
40 lines.iter().for_each(|r| wtr.write_bytes_unchecked(r));
41
42 if self.export {
43 println!("Saved to file: {}", out.display())
44 }
45
46 Ok(())
47 }
48}