use ansi_term::Colour::{Red, Yellow};
use anyhow::{Context, Result};
use clap::Parser;
use log;
use std::fs;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum IfunError {
#[error("the file is't exist")]
FileNotExist(#[from] std::io::Error),
}
#[derive(Parser)]
#[command(name = "ifun-grep")]
#[command(author = "hboot <bobolity@163.com>")]
#[command(version = "0.2.0")]
#[command(about="A simple fake grep",long_about=None)]
pub struct Config {
#[arg(short, long)]
pub search: String,
#[arg(short, long)]
pub file_path: String,
#[arg(short, long)]
pub ignore_case: bool,
}
pub fn run(config: Config) -> Result<(), anyhow::Error> {
let file_path = config.file_path.clone();
let content = fs::read_to_string(config.file_path)
.with_context(|| format!("could not read file {}", file_path))?;
let result;
if config.ignore_case {
result = find_insensitive(&config.search, &content);
} else {
result = find(&config.search, &content);
}
for line in result {
log::info!("{}", Red.on(Yellow).blink().paint(line));
}
Ok(())
}
pub fn find<'a>(search: &str, content: &'a str) -> Vec<&'a str> {
let mut result = vec![];
for line in content.lines() {
if line.contains(search) {
result.push(line);
}
}
result
}
pub fn find_insensitive<'a>(search: &str, content: &'a str) -> Vec<&'a str> {
let mut result = vec![];
let search = search.to_lowercase();
for line in content.lines() {
if line.to_lowercase().contains(&search) {
result.push(line);
}
}
result
}