test_publish_0x5/
lib.rs

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