1pub fn search<'a>(query: &str, contents: &'a str) -> impl Iterator<Item = &'a str> {
46 contents
47 .lines()
48 .filter(move |line| line.contains(query))
49}
50
51pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> impl Iterator<Item = &'a str> {
72 contents
73 .lines()
74 .filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
75}
76
77#[cfg(test)]
78mod tests {
79 use std::vec;
80
81 use super::*;
82
83 #[test]
84 fn one_result() {
85 let query = "duct";
86 let contents = "\
87Rust:
88safe, fast, productive.
89Pick three.";
90
91 let result: Vec<&str> = search(query, contents).collect();
92 assert_eq!(result, vec!["safe, fast, productive."]);
93 }
94
95 #[test]
96 fn multiple_result() {
97 let query = "ive";
98 let contents = "\
99Rust:
100really productive.
101also passive.
102probably problamatic.
103but simply lovely.
104Come dive into the world of rust.";
105
106 let result: Vec<&str> = search(query, contents).collect();
107 assert_eq!(
108 result,
109 vec![
110 "really productive.",
111 "also passive.",
112 "Come dive into the world of rust."
113 ]
114 )
115 }
116
117 #[test]
118 fn empty_content() {
119 let query = "hi";
120 let contents = "";
121
122 let result: Vec<&str> = search(query, contents).collect();
123 let expected: Vec<&str> = Vec::new();
124 assert_eq!(result, expected)
125 }
126
127 #[test]
128 fn empty_query() {
129 let query = "";
130 let contents = "\
131Rust:
132really productive.
133also passive.
134probably problamatic.
135but simply lovely.
136Come dive into the world of rust.";
137
138 let result: Vec<&str> = search(query, contents).collect();
139 let expected: Vec<&str> = contents.lines().collect();
140 assert_eq!(result, expected)
141 }
142
143 #[test]
144 fn empty_content_and_query() {
145 let query = "";
146 let contents = "";
147
148 let result: Vec<&str> = search(query, contents).collect();
149 let expected: Vec<&str> = Vec::new();
150 assert_eq!(result, expected)
151 }
152
153 #[test]
154 fn case_insensitive() {
155 let query = "rUsT";
156 let contents = "\
157Rust:
158really productive.
159also passive.
160probably problamatic.
161but simply lovely.
162Come dive into the world of rust.";
163
164 let result: Vec<&str> = search_case_insensitive(query, contents).collect();
165 assert_eq!(result, vec!["Rust:", "Come dive into the world of rust."]);
166 }
167
168 #[test]
169 fn case_sensitive() {
170 let query = "rUsT";
171 let contents = "\
172Rust:
173really productive.
174also passive.
175probably problamatic.
176but simply lovely.
177Come dive into the world of rust.";
178
179 let result: Vec<&str> = search(query, contents).collect();
180 let expected: Vec<&str> = Vec::new();
181 assert_eq!(result, expected);
182 }
183}