learning_fromdocs_minigrep/
lib.rs1use std::{env, error::Error, fs};
2
3pub struct Config {
4 pub query: String,
5 pub file_name: String,
6 pub case_sensitive: bool,
7}
8impl Config {
9 pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
10 args.next();
11
12 let query = match args.next() {
13 Some(arg) => arg,
14 None => return Err("There needs to be two arguments"),
15 };
16
17 let file_name = match args.next() {
18 Some(arg) => arg,
19 None => return Err("There needs to be two arguments"),
20 };
21 let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
22
23 Ok(Config {
24 query,
25 file_name,
26 case_sensitive,
27 })
28 }
29}
30
31pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
32 let contents = fs::read_to_string(&config.file_name)?; let results = if config.case_sensitive == true {
35 search(&config.query, &contents)
36 } else {
37 search_case_insensitive(&config.query, &contents)
38 };
39
40 for line in results {
41 println!("{}", line);
42 }
43
44 Ok(())
45}
46pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
47 contents.lines().filter(|x| x.contains(query)).collect()
48}
49pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
50 let query: &str = &query.to_lowercase();
51 contents
52 .lines()
53 .filter(|x| x.to_lowercase().contains(query))
54 .collect()
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 #[test]
61 fn case_sensitive() {
62 let query = "duct";
63 let contents = "\
64Rust:
65safe, fast, productive.
66Pick three.";
67 assert_eq!(vec!["safe, fast, productive."], search(query, contents));
68 }
69 #[test]
70 fn case_insensitive() {
71 let query = "rUsT";
72 let contents = "\
73Rust:
74safe, fast, productive.
75Pick three.
76Trust me.";
77 assert_eq!(
78 vec!["Rust:", "Trust me."],
79 search_case_insensitive(query, contents)
80 );
81 }
82}