rsv_lib/csv/
tail.rs

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        // show head n
18        let mut lines = VecDeque::new();
19
20        // header
21        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        // read
29        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}