mod convert;
mod path;
use std::fmt;
#[derive(Debug)]
pub enum Error {
Parse(Vec<String>), Regex(regex::Error),
}
impl From<regex::Error> for Error {
fn from(e: regex::Error) -> Self {
Error::Regex(e)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Parse(msgs) => write!(f, "{}", msgs.join("; ")),
Error::Regex(e) => write!(f, "{}", e),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Regex(e) => Some(e),
_ => None,
}
}
}
pub fn path_matches(path: &str, files: &[&str]) -> Result<Option<usize>, Error> {
if files.is_empty() {
return Ok(None);
}
let pattern = match path.chars().next() {
Some(c) if matches!(c, '?' | '+' | '!') => &path[c.len_utf8()..],
_ => path,
};
let parsed_path = match path::parse(pattern) {
Ok(p) => p,
Err(errs) => {
let msgs = errs.into_iter().map(|e| e.to_string()).collect();
return Err(Error::Parse(msgs));
}
};
let re = convert::path_to_regex(&parsed_path)?;
Ok(files.iter().enumerate().find(|(_, file)| re.is_match(file)).map(|(i, _)| i))
}