1use std::error::Error;
2use std::{env, fs};
3pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
4 let contents = fs::read_to_string(config.filename)?;
5 for line in search(&config.query, &contents) {
6 println!("{}", line);
7 }
8 Ok(())
9}
10pub struct Config {
11 pub query: String,
12 pub filename: String,
13 pub case_sensitive: bool,
14}
15impl Config {
16 pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
17 if args.len() < 3 {
18 return Err("输入错误");
19 }
20 args.next();
21 let query = match args.next() {
22 Some(arg) => arg,
23 None => return Err("查找的内容不存在"),
24 };
25 let filename = match args.next() {
26 Some(arg) => arg,
27 None => return Err("文件不存在"),
28 };
29 let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
30 Ok(Config {
31 query,
32 filename,
33 case_sensitive: case_sensitive,
34 })
35 }
36}
37pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
38 contents
46 .lines()
47 .filter(|line| line.contains(query))
48 .collect()
49}
50#[cfg(test)]
51mod tests {
52 use crate::*;
53 #[test]
54 fn one_result() {
55 let query = "satf";
56 let contents = "\
57 Ruest:
58 satf,faf
59 ";
60 let search = search(query, contents);
61 assert_eq!(vec!["satf"], search(query, contents));
62 }
63}