]> git.proxmox.com Git - rustc.git/blob - src/doc/book/listings/ch13-functional-features/listing-13-27/src/lib.rs
New upstream version 1.43.0+dfsg1
[rustc.git] / src / doc / book / listings / ch13-functional-features / listing-13-27 / src / lib.rs
1 use std::env;
2 use std::error::Error;
3 use std::fs;
4
5 pub struct Config {
6 pub query: String,
7 pub filename: String,
8 pub case_sensitive: bool,
9 }
10
11 // ANCHOR: here
12 impl Config {
13 pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
14 args.next();
15
16 let query = match args.next() {
17 Some(arg) => arg,
18 None => return Err("Didn't get a query string"),
19 };
20
21 let filename = match args.next() {
22 Some(arg) => arg,
23 None => return Err("Didn't get a file name"),
24 };
25
26 let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
27
28 Ok(Config {
29 query,
30 filename,
31 case_sensitive,
32 })
33 }
34 }
35 // ANCHOR_END: here
36
37 pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
38 let contents = fs::read_to_string(config.filename)?;
39
40 let results = if config.case_sensitive {
41 search(&config.query, &contents)
42 } else {
43 search_case_insensitive(&config.query, &contents)
44 };
45
46 for line in results {
47 println!("{}", line);
48 }
49
50 Ok(())
51 }
52
53 pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
54 let mut results = Vec::new();
55
56 for line in contents.lines() {
57 if line.contains(query) {
58 results.push(line);
59 }
60 }
61
62 results
63 }
64
65 pub fn search_case_insensitive<'a>(
66 query: &str,
67 contents: &'a str,
68 ) -> Vec<&'a str> {
69 let query = query.to_lowercase();
70 let mut results = Vec::new();
71
72 for line in contents.lines() {
73 if line.to_lowercase().contains(&query) {
74 results.push(line);
75 }
76 }
77
78 results
79 }
80
81 #[cfg(test)]
82 mod tests {
83 use super::*;
84
85 #[test]
86 fn case_sensitive() {
87 let query = "duct";
88 let contents = "\
89 Rust:
90 safe, fast, productive.
91 Pick three.
92 Duct tape.";
93
94 assert_eq!(vec!["safe, fast, productive."], search(query, contents));
95 }
96
97 #[test]
98 fn case_insensitive() {
99 let query = "rUsT";
100 let contents = "\
101 Rust:
102 safe, fast, productive.
103 Pick three.
104 Trust me.";
105
106 assert_eq!(
107 vec!["Rust:", "Trust me."],
108 search_case_insensitive(query, contents)
109 );
110 }
111 }
112
113 fn main() {}