unit12/
lib.rs

1use std::{env, fs};
2use std::error::Error;
3
4pub struct Config {
5    keyword: String,
6    file_path: String,
7    case_insensitive: bool,
8}
9
10impl Config {
11    pub fn new(mut args: env::Args) -> Result<Self, &'static str> {
12        args.next();
13        let keyword = match args.next() {
14            None => return Err("not find 'keyword' arguments"),
15            Some(keyword) => keyword
16        };
17        let file_path = match args.next() {
18            None => return Err("not find 'file_path' arguments"),
19            Some(file_path) => file_path
20        };
21        Ok(Config {
22            keyword,
23            file_path,
24            //std::env::var(key:<K>)用来获取操作系统环境变量参数
25            case_insensitive: env::var("CASE_INSENSITIVE").is_err(),
26        })
27    }
28}
29
30pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
31    let content = fs::read_to_string(&config.file_path)?;
32    let result = if config.case_insensitive {
33        search_case_insensitive(&config.keyword, &content)
34    } else {
35        search(&config.keyword, &content)
36    };
37    for line in result {
38        println!("{}", line);
39    }
40    Ok(())
41}
42
43pub fn search<'a>(query: &str, content: &'a str) -> Vec<&'a str> {
44    content.lines()
45        .filter(|line| line.contains(query))
46        .collect()
47}
48
49pub fn search_case_insensitive<'a>(query: &str, content: &'a str) -> Vec<&'a str> {
50    content.lines()
51        .filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
52        .collect()
53}
54
55#[cfg(test)]
56mod test {
57    use super::*;
58
59    #[test]
60    fn one_result() {
61        let query = "duct";
62        let content = "Rust\nsafe, fast, productive.\nPick three.";
63        assert_eq!(vec!["safe, fast, productive."], search(query, content));
64    }
65}