use std::fs;
use std::error::Error;
use std::env;
pub struct Config{
query:String,
filename:String,
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(arg) => arg,
None => return Err("没有查询参数")
};
let filename = match args.next() {
Some(arg) => arg,
None => return Err("没找到文件")
};
let case_sensitive=env::var("CASE_SENSITIVE").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).expect("无法读取文件!");
if config.case_sensitive {
for line in search(&config.query,&contents){
println!("{}",line)
}
}else {
for line in search_case_insensitive(&config.query,&contents){
println!("{}",line)
}
}
Ok(())
}
pub fn search<'a>(query:&str,contents:&'a str) -> Vec<&'a str>{
contents.lines().filter(|line| line.contains(query)).collect()
}
pub fn search_case_insensitive<'a>(query:&str,contents:&'a str) -> Vec<&'a str>{
contents.lines().filter(|line| line.to_uppercase().contains(&query.to_uppercase())).collect()
}
#[cfg(test)]
mod tests{
use super::*;
#[test]
fn one_result(){
let query="duct";
let contents = "duct 123";
assert_eq!(vec!["duct 123"],search(query,contents));
}
#[test]
fn case_insensitive(){
let query = "abc";
let contents = "Abc";
assert_eq!(
vec!["Abc"],
search_case_insensitive(query,contents)
)
}
}