Skip to main content

shaygrep/
lib.rs

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