minigreps/
lib.rs

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