minigrep_gdsgd/
lib.rs

1use std::error::Error;
2use std::fs;
3use std::env;
4
5/// 执行逻辑.
6/// 
7/// 这里是run函数的doc文档说明.
8pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
9  let contents = fs::read_to_string(config.filename)?;
10  
11  let results = if config.case_sensitive {
12    search(&config.query, &contents)
13  } else {
14    search_case_insensitive(&config.query, &contents)
15  };
16
17  for line in results {
18    println!("{}", line);
19  }
20  Ok(())
21}
22
23/// 配置结构体
24/// 
25/// ```
26/// pub struct Config {
27///   pub query: String,
28///   pub filename: String,
29///   pub case_sensitive: bool,
30/// }
31/// ```
32pub struct Config {
33  pub query: String,
34  pub filename: String,
35  pub case_sensitive: bool,
36}
37
38// 构造函数
39impl Config {
40  pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
41    args.next();
42
43    let query = match args.next() {
44      Some(arg) => arg,
45      None => return Err("Didn't get a query string"),
46    };
47
48    let filename = match args.next() {
49      Some(arg) => arg,
50      None => return Err("Didn't get a file name"),
51    };
52
53    let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
54
55    Ok(Config{query, filename, case_sensitive})
56  }
57}
58
59#[cfg(test)]
60mod tests {
61  use super::*;
62
63  #[test]
64  fn one_result() {
65    let query = "duct";
66    let contents = "\
67Rust:
68safe, fast, productive.
69Pick three.";
70
71    assert_eq!(
72      vec!["safe, fast, productive."],
73      search(query, contents)
74    );
75  }
76
77  #[test]
78  fn case_insensitive() {
79    let query = "rUst";
80    let contents = "\
81Rust:
82safe, fast, productive.
83Trust me.";
84
85    assert_eq!(
86      vec!["Rust:", "Trust me."],
87      search_case_insensitive(query, contents)
88    );
89  }
90}
91
92pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
93  // let mut results = Vec::new();
94
95  // for line in contents.lines() {
96  //   if (line.contains(query)) {
97  //       results.push(line);
98  //   }
99  // }
100  // results
101  contents.lines()
102    .filter(|line| line.contains(query))
103    .collect()
104}
105
106pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
107  let query = query.to_lowercase();
108  contents.lines()
109    .filter(|line| line.to_lowercase().contains(&query))
110    .collect()
111
112  // let mut results = Vec::new();
113
114  // for line in contents.lines() {
115  //   if line.to_lowercase().contains(&query) {
116  //     results.push(line);
117  //   }
118  // }
119  // results
120}
121