I'm completely new to Rust and have been learning it for the past two weeks from the book "The Rust Programming Language".
In chapter 12 "An I/O Project: Building a command-line program" the author writes a certain search function that is supposed to return a vector of &str's, and the contents of this vector will then be iterated over and printed in the calling function.
Unfortunately I'm encountering this error while running cargo run to sample.txt
Compiling rust_grep v0.1.0 (/home/atulu/Documents/rust_grep)
error[E0277]: `()` is not an iterator
--> src/lib.rs:46:17
|
46 | for line in results {
| ^^^^^^^ `()` is not an iterator
|
= help: the trait `std::iter::Iterator` is not implemented for `()`
= note: required by `std::iter::IntoIterator::into_iter`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `rust_grep`.
To learn more, run the command again with --verbose.
Here is the code in lib.rs
:
use std::fs;
use std::env;
use std::error::Error;
pub struct Config {
pub query: String, //note here, the String is not of reference
pub filename: String, //so the String value passed here should be owned
pub case_sensitive: bool, //owned by Config struct instance.
}
impl Config {
pub fn new(args: &[String]) -> Result<Config, &'static str> {
if args.len() < 3 {
return Err("Not enough arguments entered, Aborting!");
}
let query = args[1].clone();
let filename = args[2].clone();
let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
Ok(Config { query, filename, case_sensitive })
}
}
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
let contents = fs::read_to_string(config.filename)?;
let results = if config.case_sensitive {
search(&config.query, &contents);
} else {
search_case_insensitive(&config.query, &contents);
};
for line in results {
println!("{}", line);
}
Ok(())
}
pub fn search<'a> (query: &str, contents: &'a str) -> Vec<&'a str> {
let mut results = Vec::new();
for line in contents.lines() {
if line.contains(query) {
results.push(line);
}
}
results
}
pub fn search_case_insensitive<'a> (query: &str, contents: &'a str) -> Vec<&'a str> {
let query = query.to_lowercase(); //to_lowercase creates new String here
let mut results = Vec::new();
for line in contents.lines() {
if line.to_lowercase().contains(&query) {
results.push(line);
}
}
results
}
I don't understand why the results
variable in the run()
function is getting the ()
type there as I'm trying to return a vector from the search
functions.
I have a feeling that I'm making a newbie mistake here but I'm not able to figure it out.
Thanks in advance!