minigreptest/
lib.rs

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