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