taro_cli/modules/
grep.rs

1//! Finds all the lines in a file that match the substring query provided.
2//! 
3//! The search can be performed case-sensitively (default behaviour) or case-insensitively
4
5use std::{error::Error, fs};
6
7use crate::GrepConfig;
8
9fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
10  let mut results = Vec::new();
11
12  for line in contents.lines() {
13    if line.contains(query) {
14      results.push(line);
15    }
16  }
17
18  results
19}
20
21fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
22  let query = query.to_lowercase();
23
24  let mut results = Vec::new();
25
26  for line in contents.lines() {
27    if line.to_lowercase().contains(&query) {
28      results.push(line);
29    }
30  }
31
32  results
33}
34
35/// Runs the grep function using the [GrepConfig] provided.
36pub fn run_grep(config: GrepConfig) -> Result<(), Box<dyn Error>> {
37  let contents = fs::read_to_string(config.file_path)?;
38
39  let results = if config.ignore_case {
40    search_case_insensitive(&config.query, &contents)
41  } else {
42    search(&config.query, &contents)
43  };
44
45  for line in results {
46    println!("{line}");
47  }
48
49  Ok(())
50}
51
52#[cfg(test)]
53mod test {
54  use super::*;
55
56  #[test]
57  fn case_sensitive() {
58    let query = "duct";
59    let contents = "\
60Rust:
61safe, fast, productive.
62Pick three.
63Duct tape.";
64
65    assert_eq!(vec!["safe, fast, productive."], search(query, contents));
66  }
67
68  #[test]
69  fn case_insensitive() {
70    let query = "rUsT";
71    let contents = "\
72Rust:
73safe, fast, productive.
74Pick three.
75Trust me.";
76
77    assert_eq!(vec!["Rust:", "Trust me."], search_case_insensitive(query, contents));
78  }
79}