Skip to main content

minigrep_stray/
lib.rs

1use std::{fs, error::Error, env};
2
3pub struct Config {
4    pub query: String,
5    pub file_path: String,
6    pub ignore_case: bool,
7}
8
9impl Config {
10    pub fn build(mut args: impl Iterator<Item = String>) -> Result<Config, &'static str> {
11        args.next();
12        let query = match args.next() {
13            Some(arg) => arg,
14            None => return Err("Didn't get a query string"),
15        };
16
17        let file_path = match args.next() {
18            Some(arg) => arg,
19            None => return Err("Didn't get a file path"),
20        };
21
22        let ignore_case = env::var("IGNORE_CASE").is_ok();
23        Ok(Config { query, file_path, ignore_case })
24    }
25}
26
27pub fn run(config: Config) -> Result<(), Box<dyn Error>>{
28    let contents = fs::read_to_string(config.file_path)?;
29
30    let results = if config.ignore_case {
31        search_case_insensitive(&config.query, &contents)
32    } else {
33        search(&config.query, &contents)
34    };
35    for line in results {
36        println!("{line}");
37    }
38    Ok(())
39}
40
41pub fn search<'a>(query: &str, contents:&'a str) -> Vec<&'a str> {
42    contents
43        .lines()
44        .filter(|line| line.contains(query))
45        .collect()
46}
47
48pub fn search_case_insensitive<'a>(query: &str, contents:&'a str) -> Vec<&'a str> {
49    // let query = query.to_lowercase();
50    // let mut results = Vec::new();
51    // for line in contents.lines() {
52    //     if line.to_lowercase().contains(&query) {
53    //         results.push(line)
54    //     }
55    // }
56    // results
57    contents
58        .lines()
59        .filter(|line| line
60                                .to_lowercase()
61                                .contains(&query.to_lowercase()))
62        .collect()
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn case_sensitive() {
71        let query = "duct";
72        let contents = "\
73Rust:
74safe, fast, productive.
75Pick three.
76Duct tape.";
77
78        assert_eq!(
79            vec!["safe, fast, productive."],
80            search(query, contents)
81        );
82    }
83
84    #[test]
85    fn case_insensitive() {
86        let query = "rUsT";
87        let contents = "\
88Rust:
89safe, fast, productive.
90Pick three.
91Trust me.";
92
93        assert_eq!(
94            vec!["Rust:", "Trust me."],
95            search_case_insensitive(query, contents)
96        );
97    }
98}