mingrep/
lib.rs

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