Documentation
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)
        )
    }
}