use std::env;
use std::error::Error;
use std::{fs, process};
pub struct Config {
pub query: String,
pub filename: String,
pub case_sensitive:bool,
}
impl Config {
pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
args.next();
let query = match args.next(){
Some(q) => q,
None => return Err("Query string not provided")
};
let filename = match args.next(){
Some(q) => q,
None => return Err("Filename not provided")
};
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)?;
println!("With Contents:\n{}", contents);
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>{
contents.lines()
.filter(|x|x.contains(query))
.collect()
}
fn search_case_insensitive<'a>(query:&str,contents:&'a str) -> Vec<&'a str>{
contents.lines()
.filter(|x|x.to_lowercase().contains(&query.to_lowercase()))
.collect()
}
#[cfg(test)]
mod tests{
use std::env::Args;
use super::*;
#[test]
fn new_config(){
let n = Config::new(std::env::args()).expect("test failed at new config");
assert_eq!("How",n.query);
assert_eq!("minigrep_refine\\poem.txt",n.filename);
}
#[test]
fn one_result(){
let query = "How".to_string();
let contents = "I'm nobody! Who are you?\nHow do you do\n you like me \n i like you".to_string();
assert_eq!(vec!["How do you do"],search(&query,&contents));
}
#[test]
fn search_case_insensitive_test(){
let query = "how".to_string();
let contents = "I'm nobody! Who are you?\nHow do you do\n you like me \n i like you".to_string();
assert_eq!(vec!["How do you do"],search_case_insensitive(&query,&contents));
}
}