greplite/
io.rs

1use crate::{highlight::highlight_match, search::search, ApplicationError, Config};
2use regex::Regex;
3use std::{fs, io::Read};
4
5pub fn process_input<R: Read>(
6    source: &str,
7    reader: &mut R,
8    config: &Config,
9    regex: &Option<Regex>,
10) -> Result<(), ApplicationError> {
11    let mut input = String::new();
12
13    reader
14        .read_to_string(&mut input)
15        .map_err(|e| ApplicationError::IOError(e))?;
16
17    let results = search(&config.query, &input, config.ignore_case, regex);
18    print_results(config, source, results, regex)
19}
20
21pub fn process_file(
22    file_path: &str,
23    config: &Config,
24    regex: &Option<Regex>,
25) -> Result<(), ApplicationError> {
26    let content = fs::read_to_string(file_path)
27        .map_err(|_| ApplicationError::FileNotFound(file_path.to_string()))?;
28
29    let results = search(&config.query, &content, config.ignore_case, regex);
30    print_results(config, file_path, results, regex)
31}
32
33pub fn process_directory(
34    dir_path: &std::path::Path,
35    config: &Config,
36    regex: &Option<Regex>,
37) -> Result<(), ApplicationError> {
38    for entry in fs::read_dir(dir_path)
39        .map_err(|_| ApplicationError::FileNotFound(dir_path.to_string_lossy().to_string()))?
40    {
41        let entry = entry
42            .map_err(|_| ApplicationError::FileNotFound(dir_path.to_string_lossy().to_string()))?;
43        let path = entry.path();
44
45        if path.is_dir() {
46            process_directory(&path, config, regex)?;
47        } else {
48            process_file(path.to_str().unwrap(), config, regex)?;
49        }
50    }
51
52    Ok(())
53}
54
55fn print_results(
56    config: &Config,
57    source: &str,
58    results: Vec<(usize, &str)>,
59    regex: &Option<Regex>,
60) -> Result<(), ApplicationError> {
61    if results.is_empty() {
62        return Ok(());
63    }
64
65    for (line_num, line) in results {
66        let highlighted_line = if config.enable_highlighting {
67            highlight_match(&config.query, line, config.ignore_case, &regex)
68        } else {
69            line.to_string()
70        };
71
72        if config.show_line_numbers {
73            println!("{}:{}: {}", source, line_num, highlighted_line);
74        } else {
75            println!("{}:{}", source, highlighted_line);
76        }
77    }
78    Ok(())
79}