slier_minigrep/
lib.rs

1//! Main code for parsing and performing the search
2use std::env;
3use std::fs::File;
4use std::io::Read;
5use std::env::Args;
6use std::error::Error;
7
8/// Struct to hold cofiguration value
9pub struct Config {
10    query: String,
11    filename: String,
12    case_sensitive: bool,
13}
14
15impl Config {
16    pub fn new(mut args: Args) -> Result<Config, &'static str> {
17        args.next();
18
19        let _query = match args.next() {
20            Some(v) => v,
21            None => return Err("Didnt get query to search for")
22        };
23
24        let _filename = match args.next() {
25            Some(v) => v,
26            None => return Err("Didnt get filename for searching")
27        };
28
29        let _case_sensitive = env::var("CASE_INSENSITIVE").is_err();
30
31        return Result::Ok(
32            Config {
33                query: _query,
34                filename: _filename,
35                case_sensitive: _case_sensitive,
36            }
37        );
38    }
39}
40
41/// Main code to load the file and perform the search
42pub fn run(config: Config) -> Result<(), Box<Error>> {
43    let mut file = File::open(config.filename.clone())?;
44    let mut content = String::new();
45
46    file.read_to_string(&mut content)?;
47
48    let results = if config.case_sensitive {
49        search_sensitive(&config.query, &content)
50    } else {
51        search_insensitive(&config.query, &content)
52    };
53
54    for result in results {
55        println!("{}", result);
56    }
57
58    Ok(())
59}
60
61/// Search in an sensitive way
62pub fn search_sensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
63    contents.lines().filter(|line| line.contains(query)).collect()
64}
65
66/// Search in an insensitive way
67pub fn search_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
68    let query = query.to_lowercase();
69    contents.lines().filter(|line| line.contains(&query)).collect()
70}
71
72
73#[cfg(test)]
74mod test {
75    use crate::*;
76
77    #[test]
78    fn case_sensitive() {
79        let query = "duct";
80        let contents = "Rust:\nsafe, fast, productive\nPick three\nDuct Tape";
81        assert_eq!(vec!["safe, fast, productive"], search_sensitive(query, contents));
82    }
83
84    #[test]
85    fn case_insensitive() {
86        let query = "rUsT";
87        let contents = "Rust:\nsafe, fast, productive\nPick three.\nTrust me";
88        assert_eq!(vec!["Rust:", "Trust me"], search_insensitive(query, contents));
89    }
90}