r_rg/
lib.rs

1/*
2 * @LastEditors: Ihoey
3 * @LastEditTime: 2022-03-20 11:19:03
4 * @Email: mail@ihoey.com
5 * @Date: 2022-03-19 19:21:22
6 * @Author: Ihoey
7 */
8
9use std::env;
10use std::error::Error;
11use std::fs;
12
13pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
14  let contents = fs::read_to_string(config.filename)?;
15
16  let result = if config.case_sensitive {
17    search(&config.query, &contents)
18  } else {
19    search_case_insensitive(&config.query, &contents)
20  };
21
22  for line in result {
23    println!("{}", line);
24  }
25
26  return Ok(());
27}
28
29pub struct Config {
30  pub query: String,
31  pub filename: String,
32  pub case_sensitive: bool,
33}
34
35impl Config {
36  pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
37    if args.len() < 3 {
38      return Err("not enough arguments");
39    }
40    args.next();
41
42    let query = match args.next() {
43      Some(arg) => arg,
44      None => return Err("Didn't get a query string"),
45    };
46    let filename = match args.next() {
47      Some(arg) => arg,
48      None => return Err("Didn't get a file name"),
49    };
50    let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
51
52    Ok(Config {
53      query,
54      filename,
55      case_sensitive,
56    })
57  }
58}
59
60pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
61  // let mut results = Vec::new();
62  // for line in contents.lines() {
63  //   if line.contains(query) {
64  //     results.push(line);
65  //   }
66  // }
67  // results
68
69  contents
70    .lines()
71    .filter(|line| line.contains(&query))
72    .collect()
73}
74
75pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
76  // let query = query.to_lowercase();
77  // let mut results = Vec::new();
78  // for line in contents.lines() {
79  //   if line.to_lowercase().contains(&query) {
80  //     results.push(line);
81  //   }
82  // }
83  // results
84
85  contents
86    .lines()
87    .filter(|line| line.to_lowercase().contains(&query))
88    .collect()
89}
90
91#[cfg(test)]
92mod tests {
93  use super::*;
94
95  #[test]
96  fn one_result() {
97    let query = "ihoey";
98    let contents = "my name is xixi\n
99ihoey
100IHOEY
101and i am from china";
102
103    assert_eq!(vec!["my name is xixi"], search(query, contents));
104  }
105
106  #[test]
107  fn case_insensitive() {
108    let query = "IHOEY";
109    let contents = "my name is xixi\n
110ihoey
111IHOEY
112and i am from china";
113
114    assert_eq!(
115      vec!["ihoey", "IHOEY"],
116      search_case_insensitive(query, contents)
117    );
118  }
119}