1use std::error::Error;
2use std::{env, fs};
3
4pub struct Config{
5 pub query:String,
6 pub filename:String,
7 pub case_sensitive:bool,
8}
9
10impl Config{
11 pub fn new(args: &[String]) -> Result<Config,&'static str>{
12 if args.len()<3{
13 return Err("not enough arguments");
14 }
15 let query=args[1].clone();
16 let filename=args[2].clone();
17 let case_sensitive=env::var("insensitive").is_err();
18 Ok(Config{query,filename,case_sensitive})
19 }
20}
21
22pub fn run(config:Config) -> Result<(),Box<dyn Error>>{
23 let contents= fs::read_to_string(config.filename)?;
24 let results=if config.case_sensitive {
26 search(&config.query, &contents)
27 }else{
28 search_case_insensitive(&config.query, &contents)
29 };
30 for line in results{
31 println!("{}",line);
32 }
33 Ok(())
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 #[test]
40 fn one_result(){
41 let query="duct";
42 let contents= "\
43Rust:
44safe,fast,productive.
45Pick three.";
46 assert_eq!(vec!["safe,fast,productive."],search(query,contents));
47 }
48}
49
50pub fn search<'a>(query:&str,contents:&'a str) -> Vec<&'a str>{
51 let mut results=Vec::new();
52 for line in contents.lines(){
53 if line.contains(query){
54 results.push(line);
55 }
56 }
57 results
58}
59
60pub fn search_case_insensitive<'a>(query:&str,contents:&'a str) -> Vec<&'a str>{
61 let query=query.to_lowercase();
62 contents.lines().filter(|line| line.to_lowercase().contains(&query)).collect()
63}