use std::env;
use std::error::Error;
use std::fs;
use std::process;
fn main(){
let args : Vec<String> = env::args().collect();
let config = Config::new(&args).unwrap_or_else(|err| {
eprintln!("{}",err); process::exit(1);
});
if let Err(e) = run(config){
eprintln!("{}",e); process::exit(1);
}
}
fn run(config:Config)->Result<(),Box<dyn Error>>{
let contents = fs::read_to_string(config.filename)?;
println!("case_sensitive:{}",config.case_sensitive);
let res = if !config.case_sensitive {
search(&config.query,&contents)
}else{
search_case_insensitive(&config.query,&contents)
};
for line in res {
println!("{}",line)
}
Ok(())
}
fn search(query:&str,content:&str) -> Vec<String>{
let mut res = vec![];
for line in content.lines() {
if line.contains(query) {
res.push(line.to_string());
}
}
res
}
fn search_case_insensitive(query:&str,content:&str ) -> Vec<String>{
let query = query.to_lowercase();
let mut res = vec![];
for line in content.lines() {
if line.to_lowercase().contains(&query) {
res.push(line.to_string());
}
}
res
}
struct Config {
query:String,
filename:String,
case_sensitive:bool
}
impl Config{
fn new(args:&[String])->Result<Config, &'static str>{
if args.len() < 3 {
return Err("not enough arguments");
}
let query = args[1].clone();
let filename = args[2].clone();
println!("{},{}",query,filename);
let case_sensitive = env::var("CASE_SENSITIVE").is_err();
Ok(Config{ query,filename,case_sensitive:case_sensitive})
}
}