anyu_minigrep/
lib.rs

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