extern crate regex;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::path;
struct Config {
target: path::PathBuf,
regex: regex::Regex,
}
impl Config {
fn new(args: Vec<String>) -> Result<Config, Box<Error>> {
let config = Config {
target: path::PathBuf::from(&args[1]),
regex: regex::Regex::new(&args[2])?,
};
if !config.target.is_file() {
return Err(From::from("Path does not lead to a file"));
}
Ok(config)
}
}
pub fn grep(args: Vec<String>) -> Result<String, Box<Error>> {
if args.len() < 3 {
print_help();
println!("{:?}", args);
Err(From::from("Invalid length of arguments"))
} else if args.len() > 3 {
print_help();
println!("{:?}", args);
Err(From::from("Invalid length of arguments"))
} else {
let config: Config = Config::new(args)?;
let contents = read_file(&config.target)?;
let contents = contents.split("\n");
let mut result: String = String::from("");
for s in contents {
let mut pushed = false;
for cap in config.regex.captures_iter(&s) {
if cap.len() > 0 && !pushed {
result.push_str(s);
pushed = true;
}
}
if pushed {
result.push_str("\n");
}
}
result.pop();
Ok(result)
}
}
fn read_file(target: &path::PathBuf) -> Result<String, Box<Error>> {
let mut file: File = File::open(target).expect("File not found");
let mut contents: String = String::new();
file.read_to_string(&mut contents).expect("Cannot read file");
Ok(contents)
}
fn print_help() {
let help_message = &(String::from(
"\n ============ MiniGrep v") + env!("CARGO_PKG_VERSION") +
" ============ \n\n" +
" Arguments:\n" +
" target - The target file to be searched\n" +
" regex - The regular expression to search by (default: .)\n" +
" --help - Display this message\n");
println!("{}", help_message);
}