smolgrep/src/parser.rs

56 lines
1.4 KiB
Rust
Raw Normal View History

use std::{
fs::File,
io::{BufRead, BufReader},
};
use anyhow::Context;
2026-07-27 09:04:19 +00:00
use regex::Regex;
use crate::matches::{self, Match, Matches};
pub fn read_lines(
file_path: &str,
) -> anyhow::Result<impl Iterator<Item = std::io::Result<String>>, anyhow::Error> {
if file_path.is_empty() {
return Err(anyhow::anyhow!("File path cannot be empty"));
}
let file =
File::open(file_path).with_context(|| format!("failed to open file: {file_path}"))?;
let reader = BufReader::new(file);
Ok(reader.lines())
}
fn get_file_name_from_path(file_path: &str) -> String {
match file_path.rsplit('/').next() {
Some(name) => name.into(),
None => file_path.into(),
}
}
2026-07-27 09:04:19 +00:00
pub fn match_pattern(
iter: impl Iterator<Item = std::io::Result<String>>,
pattern: &str,
file_path: &str,
) -> anyhow::Result<Matches, anyhow::Error> {
2026-07-27 09:04:19 +00:00
let reg = Regex::new(pattern).with_context(|| format!("invalid regex: {:?}", pattern))?;
let mut matches = Vec::new();
for (idx, line) in iter.enumerate() {
let line = line?;
2026-07-27 09:04:19 +00:00
if reg.is_match(&line) {
let m = Match {
line_number: idx,
text: line,
file_name: get_file_name_from_path(file_path),
};
matches.push(m);
}
}
2026-07-27 09:04:19 +00:00
Ok(Matches { items: matches, pattern: String::from(pattern) })
}