minigrep_dalingtao/
lib.rs1use std::fs;
6use std::error::Error;
7
8pub struct Config<'a> {
9 pattern: &'a String,
10 filename: &'a String,
11}
12
13#[derive(Debug)]
14#[derive(PartialEq)]
15pub struct Row {
16 row: String,
17 row_num: usize
18}
19
20impl Row {
21 pub fn new(row: String, row_num: usize) -> Self {
22 Row{row, row_num}
23 }
24}
25impl ToString for Row {
26 fn to_string(&self) -> String {
27 format!("{} : {}", self.row_num, self.row)
28 }
29}
30
31impl<'a> Config<'a> {
32 pub fn new(pattern: &'a String, filename: &'a String) -> Self {
33 Config { pattern, filename }
34 }
35}
36
37pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
38 let contents = dbg!(fs::read_to_string(config.filename)?);
39 let rows = filter(config.pattern, &contents);
40 for row in rows.iter() {
41 println!("{}", row.to_string());
42 }
43 Ok(())
44}
45
46pub fn filter(pattern: &String, content: &String) -> Vec<Row> {
57 let res: Vec<Row> = content.split("\r\n").enumerate().filter(|(index, row)| {
58 row.contains(pattern)
59 })
60 .map(|(index, row)| { Row::new(row.to_string(), index) })
61 .collect();
62 res
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn filter_test() {
71 let ret = filter(&"human".to_string(), &"I'm a human\r\nI will never die".to_string());
72 assert_eq!(ret, vec![Row{row_num: 0, row: "I'm a human".to_string()}]);
73 }
74}