1use 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
35pub 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}