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