2026-07-27 08:43:48 +00:00
|
|
|
use std::{
|
|
|
|
|
fs::File,
|
|
|
|
|
io::{BufRead, BufReader},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use anyhow::Context;
|
2026-07-27 09:04:19 +00:00
|
|
|
use regex::Regex;
|
2026-07-27 08:43:48 +00:00
|
|
|
|
|
|
|
|
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())
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-27 09:04:19 +00:00
|
|
|
pub fn match_pattern(
|
|
|
|
|
iter: impl Iterator<Item = std::io::Result<String>>,
|
|
|
|
|
pattern: &str,
|
|
|
|
|
) -> anyhow::Result<Vec<String>, anyhow::Error> {
|
|
|
|
|
let reg = Regex::new(pattern).with_context(|| format!("invalid regex: {:?}", pattern))?;
|
|
|
|
|
let lines = iter.collect::<std::io::Result<Vec<_>>>()?;
|
|
|
|
|
|
|
|
|
|
let matches = lines.into_iter().filter(|line| reg.is_match(line)).collect::<Vec<_>>();
|
|
|
|
|
|
|
|
|
|
Ok(matches)
|
2026-07-27 08:43:48 +00:00
|
|
|
}
|