1use crate::args::Search;
2use crate::utils::column::Columns;
3use crate::utils::filename::new_file;
4use crate::utils::regex::Re;
5use crate::utils::{cli_result::CliResult, writer::Writer};
6use std::io::{self, BufRead};
7
8impl Search {
9 pub fn io_run(&self) -> CliResult {
10 let out = new_file("searched.csv");
12 let mut wtr = Writer::file_or_stdout(self.export, &out)?;
13 let mut cols = Columns::new(&self.cols);
14 let mut filter = Columns::new(&self.filter);
15
16 let mut rdr = io::stdin().lock().lines();
18
19 if !self.no_header {
21 let Some(r) = rdr.next() else { return Ok(()) };
22 let r = r?;
23
24 let mut fields = self.split_row_to_vec(&r);
25 cols = cols.total_col(fields.len()).parse();
26 filter = filter.total_col(fields.len()).parse();
27
28 if cols.select_all {
29 wtr.write_str_unchecked(&r)
30 } else {
31 fields = cols.iter().map(|&i| fields[i]).collect();
32 wtr.write_fields_unchecked(&fields);
33 }
34 }
35
36 let re = Re::new(&self.pattern)?;
38 let mut matched = 0;
39 for r in rdr {
40 let r = r?;
41
42 if !cols.parsed {
43 let n = self.row_field_count(&r);
44 cols = cols.total_col(n).parse();
45 }
46 if !filter.parsed {
47 let n = self.row_field_count(&r);
48 filter = filter.total_col(n).parse();
49 }
50
51 match (cols.select_all, filter.select_all) {
52 (true, true) => {
53 if re.is_match(&r) {
54 matched += 1;
55 wtr.write_str(&r)?;
56 }
57 }
58 (true, false) => {
59 let f = self.split_row_to_vec(&r);
60 if filter.iter().any(|&i| re.is_match(f[i])) {
61 wtr.write_str(&r)?;
62 }
63 }
64 (false, true) => {
65 if re.is_match(&r) {
66 let r = self.split_row_to_vec(&r);
67 let r = cols.iter().map(|&i| r[i]).collect::<Vec<_>>();
68 wtr.write_fields_unchecked(&r)
69 }
70 }
71 (false, false) => {
72 let r = self.split_row_to_vec(&r);
73 if filter.iter().any(|&i| re.is_match(r[i])) {
74 let r = cols.iter().map(|&i| r[i]).collect::<Vec<_>>();
75 wtr.write_fields_unchecked(&r)
76 }
77 }
78 }
79 }
80
81 if self.export {
82 println!("Matched rows: {matched}");
83 println!("Saved to file: {}", out.display())
84 }
85
86 Ok(())
87 }
88}