mfaizudd_minigrep/
lib.rs

1use std::{env, error::Error, fs};
2
3#[cfg(test)]
4mod tests {
5    use super::*;
6
7    #[test]
8    fn case_sensitive() {
9        let query = "duck";
10        let contents = "\
11From troubles of the world
12I turn to ducks,
13Beautiful comical things
14Duck supremacy";
15
16        assert_eq!(vec!["I turn to ducks,"], search(query, contents));
17    }
18
19    #[test]
20    fn case_insensitive() {
21        let query = "DuCk";
22        let contents = "\
23From troubles of the world
24I turn to ducks,
25Beautiful comical things
26Duck supremacy";
27
28        assert_eq!(
29            vec!["I turn to ducks,", "Duck supremacy"],
30            search_case_insensitive(query, contents)
31        );
32    }
33}
34
35pub fn run(config: &Config) -> Result<(), Box<dyn Error>> {
36    let contents = fs::read_to_string(&config.filename)?;
37
38    let result = if config.case_sensitive {
39        search(&config.query, &contents)
40    } else {
41        search_case_insensitive(&config.query, &contents)
42    };
43
44    for line in result {
45        println!("{}", line);
46    }
47
48    Ok(())
49}
50
51pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
52    contents
53        .lines()
54        .filter(|line| line.contains(query))
55        .collect()
56}
57
58pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
59    let query = &query.to_lowercase();
60    contents
61        .lines()
62        .filter(|line| line.to_lowercase().contains(query))
63        .collect()
64}
65
66pub struct Config {
67    pub query: String,
68    pub filename: String,
69    pub case_sensitive: bool,
70}
71
72impl Config {
73    pub fn new(mut args: env::Args) -> Result<Config, &'static str> {
74        args.next();
75
76        let query = match args.next() {
77            Some(arg) => arg,
78            None => return Err("Didn't get a query string"),
79        };
80        
81        let filename = match args.next() {
82            Some(arg) => arg,
83            None => return Err("Didn't gate a file name"),
84        };
85        let case_sensitive = if !env::var("CASE_INSENSITIVE").is_err() {
86            env::var("CASE_INSENSITIVE").is_err()
87        } else {
88            args.next().is_none()
89        };
90
91        Ok(Config {
92            query,
93            filename,
94            case_sensitive,
95        })
96    }
97}