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