Skip to main content

minigrep_skyler/
lib.rs

1//! # My Crate
2//!
3//! `my_crate` is a collection of utilities to make performing certain
4//! calculations more convenient.
5
6use std::env;
7use std::error::Error;
8use std::fs;
9
10///
11/// config de run 方法
12///
13/// # examples
14///
15/// ```
16/// let result = config::run(config: Config)
17/// println!(result)
18/// ```
19///
20///
21pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
22    println!("config: {:?}", config);
23    let contents = fs::read_to_string(config.file_name)?;
24
25    let vecs = if config.case_sensitive {
26        search(&config.query_word, &contents)
27    } else {
28        search_no_case_sensitive(&config.query_word, &contents)
29    };
30
31    for line in &vecs {
32        println!("line:{}", line);
33    }
34    println!("vecs:{:?}", vecs);
35    Ok(())
36}
37
38#[derive(Debug)]
39pub struct Config {
40    query_word: String,
41    file_name: String,
42    case_sensitive: bool,
43}
44
45// pub fn parse_config(args: &[String]) -> Config {
46//     let query_word = args[1].to_string();
47//     let file_name = args[2].to_string();
48
49//     Config {
50//         query_word,
51//         file_name,
52//     }
53// }
54
55impl Config {
56    pub fn new(mut args: env::Args) -> Result<Config, &'static str> {
57        args.next();
58
59        let query_word = match args.next() {
60            Some(v) => v,
61            None => return Err("Didn't get a query string"),
62        };
63
64        let file_name = match args.next() {
65            Some(v) => v,
66            None => return Err("Didn't get a file name"),
67        };
68
69        let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
70        println!("case_sensitive:{}", case_sensitive);
71        Ok(Config {
72            query_word,
73            file_name,
74            case_sensitive,
75        })
76    }
77}
78
79fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
80    // let mut vecs = Vec::new();
81    // for line in contents.lines() {
82    //     if line.contains(query) {
83    //         vecs.push(line);
84    //     }
85    // }
86    // vecs
87
88    contents
89        .lines()
90        .filter(|line| line.contains(query))
91        .collect()
92}
93
94fn search_no_case_sensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
95    let mut vecs = Vec::new();
96    let query = query.to_lowercase();
97
98    for line in contents.lines() {
99        if line.to_lowercase().contains(&query) {
100            vecs.push(line);
101        }
102    }
103
104    vecs
105}
106
107#[cfg(test)]
108mod tests {
109
110    #[test]
111    fn test() {
112        let query = "Duct";
113        let contents = "\
114Rust:
115safe, fast, productive.
116Pick three";
117
118        assert_eq!(
119            vec!["safe, fast, productive."],
120            super::search(query, contents)
121        );
122    }
123
124    #[test]
125    fn search_no_case_sensitive() {
126        let query = "Duct";
127        let contents = "\
128Rust:
129safe, fast, productive.
130Ductory";
131        assert_eq!(
132            vec!["Ductory"],
133            super::search_no_case_sensitive(query, contents)
134        );
135    }
136}