minigrep_lucky/
lib.rs

1//! 当前包完成判断逻辑
2use std::{env, error::Error, fs, process};
3
4#[derive(Debug)]
5pub struct CommandInput {
6    query: String,
7    filename: String,
8    case_sensitive: bool,
9}
10
11impl CommandInput {
12    pub fn new(mut args: env::Args) -> Result<CommandInput, &'static str> {
13        args.next();
14
15        let query = match args.next() {
16            Some(i) => i,
17            None => return Err("Didn't get query param"),
18        };
19
20        let filename = match args.next() {
21            Some(i) => i,
22            None => return Err("Didn't get filename param"),
23        };
24
25        // 当前环境变量是否有被设置,没有被设置会 true
26        let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
27
28        return Ok(CommandInput {
29            query,
30            filename,
31            case_sensitive,
32        });
33    }
34}
35
36/// 
37/// 主体逻辑,完成 文件读取-匹配 等操作
38pub fn run(command: CommandInput) -> Result<(), Box<dyn Error>> {
39    let contents = fs::read_to_string(&command.filename)?;
40
41    let result = if command.case_sensitive {
42        search_case_sensitive(&command.query, &contents)
43    } else {
44        search_case_insensitive(&command.query, &contents)
45    };
46
47    for line in result {
48        println!("{}", line);
49    }
50
51    Ok(())
52}
53
54pub fn search_case_sensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
55    let mut result: Vec<&str> = vec![];
56    for item in contents.lines() {
57        if item.contains(query) {
58            result.push(item);
59        }
60    }
61
62    result
63}
64
65pub fn search_case_sensitive_function_style<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
66    contents
67        .lines()
68        .filter(|line| line.contains(query))
69        .collect()
70}
71
72pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
73    let query = query.to_lowercase();
74
75    let mut result = Vec::new();
76    for line in contents.lines() {
77        if line.to_lowercase().contains(&query) {
78            result.push(line);
79        }
80    }
81
82    return result;
83}
84
85pub fn search_case_insensitive_function_stype<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
86    let query = query.to_lowercase();
87    contents
88        .lines()
89        .filter(|line| line.to_lowercase().contains(&query))
90        .collect()
91}
92
93#[cfg(test)]
94mod tests {
95    use std::vec;
96
97    use crate::{search_case_insensitive, search_case_sensitive};
98
99    #[test]
100    fn case_sensitive() {
101        let query = "duct";
102        let contents = "
103Rust: 
104safe, fast, productive.
105Pick three.";
106        assert_eq!(
107            vec!["safe, fast, productive."],
108            search_case_sensitive(query, contents)
109        );
110    }
111
112    #[test]
113    fn case_insensitive() {
114        let query = "rUst";
115        let contents = "
116Rust: 
117safe, fast, productive.
118Pick three.
119Trust me.";
120
121        assert_eq!(
122            vec!["Rust: ", "Trust me."],
123            search_case_insensitive(query, contents)
124        );
125    }
126}