rsv_lib/csv/
slice.rs

1use crate::args::Slice;
2use crate::utils::cli_result::CliResult;
3use crate::utils::filename::new_path;
4use crate::utils::writer::Writer;
5use std::fs::File;
6use std::io::BufRead;
7use std::io::BufReader;
8
9impl Slice {
10    pub fn csv_run(&self) -> CliResult {
11        let path = &self.path();
12
13        // wtr and rdr
14        let out = new_path(path, "-slice");
15        let mut wtr = Writer::file_or_stdout(self.export, &out)?;
16        let mut rdr = BufReader::new(File::open(path)?);
17
18        // header
19        if !self.no_header {
20            let mut buf = vec![];
21            let Ok(_) = rdr.read_until(b'\n', &mut buf) else {
22                return Ok(());
23            };
24            wtr.write_bytes_unchecked(&buf);
25        }
26
27        // slice
28        match self.index {
29            Some(index) => write_by_index(&mut rdr, &mut wtr, index),
30            None => {
31                let e = self
32                    .end
33                    .or_else(|| self.length.map(|l| self.start + l))
34                    .unwrap_or(usize::MAX - 10);
35                write_by_range(&mut rdr, &mut wtr, self.start, e);
36            }
37        }
38
39        if self.export {
40            println!("Saved to file: {}", out.display())
41        }
42
43        Ok(())
44    }
45}
46
47fn write_by_index(rdr: &mut BufReader<File>, wtr: &mut Writer, index: usize) {
48    let mut buf = vec![];
49    let mut n = 0;
50
51    while let Ok(bytes) = rdr.read_until(b'\n', &mut buf) {
52        if bytes == 0 {
53            break;
54        }
55
56        if n == index {
57            wtr.write_bytes_unchecked(&buf[..bytes]);
58            break;
59        }
60
61        buf.clear();
62        n += 1;
63    }
64}
65
66fn write_by_range(rdr: &mut BufReader<File>, wtr: &mut Writer, start: usize, end: usize) {
67    let mut buf = vec![];
68    let mut n = 0;
69
70    while let Ok(bytes) = rdr.read_until(b'\n', &mut buf) {
71        if bytes == 0 || n >= end {
72            break;
73        }
74
75        if n >= start && n < end {
76            wtr.write_bytes_unchecked(&buf[..bytes]);
77        }
78
79        buf.clear();
80        n += 1;
81    }
82}