From 5ef16fdc3495862adf2990c6e8dd9f859650fda7 Mon Sep 17 00:00:00 2001 From: Sarthak Kumar Date: Mon, 6 May 2024 01:40:24 +0530 Subject: [PATCH] added support for PIPE --- grepr/src/bm.rs | 29 +++++++++++++ grepr/src/cli.rs | 94 ++++++++++++++-------------------------- grepr/src/main.rs | 13 ++++-- grepr/src/regex_match.rs | 31 +++++++++++++ 4 files changed, 102 insertions(+), 65 deletions(-) diff --git a/grepr/src/bm.rs b/grepr/src/bm.rs index c6c0eb2..87c90a4 100644 --- a/grepr/src/bm.rs +++ b/grepr/src/bm.rs @@ -2,6 +2,10 @@ pub struct BoyerMoore; +use std::io; +use std::io::Write; +use crate::cli::{write_result, InputLinesIterator}; + const MAX_U8: usize = u8::MAX as usize; impl BoyerMoore { @@ -59,6 +63,31 @@ impl BoyerMoore { } } +pub fn bm_search(pat: &str, mut lines_iter: InputLinesIterator) { + let pat_bytes = pat.as_bytes(); + let mut line_num = 0_usize; + let match_len = pat.len(); + + let stdout = io::stdout(); + let mut handle = stdout.lock(); + + while let Some(line) = lines_iter.next() { + match line { + Ok(line) => { + let inp_bytes = line.as_bytes(); + let res = BoyerMoore::find_match(inp_bytes, pat_bytes); + + if res.len() != 0 { + write_result(&mut handle, inp_bytes, &res, match_len, Some(line_num)); + } + line_num += 1; + }, + Err(err) => panic!("{}", err) + } + } + + handle.flush().unwrap(); +} #[cfg(test)] mod tests { diff --git a/grepr/src/cli.rs b/grepr/src/cli.rs index 6c89ba4..082920f 100644 --- a/grepr/src/cli.rs +++ b/grepr/src/cli.rs @@ -2,12 +2,24 @@ use clap::{command, Parser}; use colored::Colorize; use std::{ - fs::File, io::{self, BufRead, BufReader, Lines, StdoutLock, Write} + fs::File, io::{self, BufRead, BufReader, Lines, StdinLock, StdoutLock, Write} }; -use crate::bm::BoyerMoore; -use crate::regex_match::match_regex_pat; -use regex::Regex; +pub enum InputLinesIterator{ + FileLines(Lines>), + StdioLines(Lines>) +} + +impl Iterator for InputLinesIterator { + type Item = Result; + + fn next(&mut self) -> Option { + match self { + Self::FileLines(iter) => iter.next(), + Self::StdioLines(iter) => iter.next() + } + } +} #[derive(Parser)] @@ -17,67 +29,14 @@ pub struct Args{ pub pattern: String, /// input file path - pub input: String, + pub file: Option, /// Use exact match, without regular experessions #[arg(short, long)] pub exact: bool } -pub fn regex_search(pat: &str, path: &str) { - - let mut hay = read_lines_from_file(path); - let re_pat = Regex::new(pat).unwrap(); - let mut line_num = 0_usize; - let match_len = pat.len(); - - let stdout = io::stdout(); - let mut handle = stdout.lock(); - - while let Some(line) = hay.next(){ - match line { - Ok(line) => { - let res = match_regex_pat(&re_pat, &line); - - if res.len() != 0{ - write_result(&mut handle, line.as_bytes(), &res, match_len, Some(line_num)); - } - line_num += 1; - }, - Err(err) => panic!("{}", err) - } - } - handle.flush().unwrap(); -} - -pub fn bm_search(patt: &str, input: &str) { - let patt_bytes = patt.as_bytes(); - let mut inp_str = read_lines_from_file(input); - let mut line_num = 0_usize; - let match_len = patt.len(); - - let stdout = io::stdout(); - let mut handle = stdout.lock(); - - while let Some(line) = inp_str.next() { - match line { - Ok(line) => { - let inp_bytes = line.as_bytes(); - let res = BoyerMoore::find_match(inp_bytes, patt_bytes); - - if res.len() != 0 { - write_result(&mut handle, inp_bytes, &res, match_len, Some(line_num)); - } - line_num += 1; - }, - Err(err) => panic!("{}", err) - } - } - - handle.flush().unwrap(); -} - -fn write_result(handle: &mut StdoutLock<'static>, content: &[u8], matches: &Vec, match_len: usize, line_num: Option){ +pub fn write_result(handle: &mut StdoutLock<'static>, content: &[u8], matches: &Vec, match_len: usize, line_num: Option){ // i: content iterrator, j is match iterator let mut i = 0_usize; @@ -114,11 +73,24 @@ fn write_result(handle: &mut StdoutLock<'static>, content: &[u8], matches: &Vec< } // Returns tuple with (Content, Query) -fn read_lines_from_file(path: &str) -> Lines> { - +pub fn read_lines_from_file(path: &str) -> Lines> { + let file = File::open(path).unwrap(); let buf = BufReader::new(file); buf.lines() + +} + +pub fn read_lines_from_stdio() -> Lines> { + let stdin = io::stdin(); + stdin.lines() +} + +pub fn read_lines(path: Option<&str>) -> InputLinesIterator{ + match path { + Some(path) => InputLinesIterator::FileLines(read_lines_from_file(path)), + None => InputLinesIterator::StdioLines(read_lines_from_stdio()) + } } diff --git a/grepr/src/main.rs b/grepr/src/main.rs index 7b349c9..67c64f1 100644 --- a/grepr/src/main.rs +++ b/grepr/src/main.rs @@ -3,17 +3,22 @@ mod bm; mod regex_match; use clap::Parser; -use cli::{bm_search, regex_search}; +use cli::read_lines; +use regex_match::regex_search; +use bm::bm_search; + fn main() { let args = cli::Args::parse(); - let (exact, patt, path) = (args.exact, args.pattern.as_ref(), args.input.as_ref()); + let (exact, pat, file) = (args.exact, args.pattern.as_ref(), args.file.as_deref()); + + let line_iter = read_lines(file); if exact { - bm_search(patt, path); + bm_search(pat, line_iter); } else { - regex_search(patt, path) + regex_search(pat, line_iter) } } diff --git a/grepr/src/regex_match.rs b/grepr/src/regex_match.rs index 749b2fc..afd1f35 100644 --- a/grepr/src/regex_match.rs +++ b/grepr/src/regex_match.rs @@ -1,6 +1,37 @@ + +use std::io::Write; use regex::Regex; +use std::io; +use crate::cli::{write_result, InputLinesIterator}; + + pub fn match_regex_pat(pat: &Regex, hay: &str) -> Vec { pat.find_iter(hay).map(|m: regex::Match<'_>| m.start()).collect() +} + +pub fn regex_search(pat: &str, mut lines_iter: InputLinesIterator) { + + let re_pat = Regex::new(pat).unwrap(); + let mut line_num = 0_usize; + let match_len = pat.len(); + + let stdout = io::stdout(); + let mut handle = stdout.lock(); + + while let Some(line) = lines_iter.next(){ + match line { + Ok(line) => { + let res = match_regex_pat(&re_pat, &line); + + if res.len() != 0{ + write_result(&mut handle, line.as_bytes(), &res, match_len, Some(line_num)); + } + line_num += 1; + }, + Err(err) => panic!("{}", err) + } + } + handle.flush().unwrap(); } \ No newline at end of file