minigrep_daniel/
lib.rs

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