use structopt::StructOpt;
use std::{error::Error, fmt};
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::path::PathBuf;
#[derive(Debug)]
struct FileNotFoundError(String);
impl Error for FileNotFoundError {}
impl fmt::Display for FileNotFoundError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Oh no, something bad went down")
}
}
#[derive(Debug, StructOpt)]
struct Opts {
pattern: String,
#[structopt(parse(from_os_str))]
path: PathBuf
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let opts = Opts::from_args();
println!("{:?}", opts);
let file = match File::open(&opts.path) {
Ok(content) => { content },
Err(error) => { return Err(Box::new(FileNotFoundError(format!("Error reading `{}`: {}", &opts.path.to_str().unwrap(), error)))) }
};
let reader = BufReader::new(file);
for (num, line) in reader.lines().enumerate() {
let value = line?;
if value.contains(&opts.pattern) {
println!("{}. {}", num, value);
}
}
Ok(())
}