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