gderu/
lib.rs

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