minigrep_najeeb/
lib.rs

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