diff options
Diffstat (limited to 'src/parser.rs')
-rw-r--r-- | src/parser.rs | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/src/parser.rs b/src/parser.rs index 1d3f159..2eec51c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,35 +1,36 @@ -use std::{fmt::Display, path::PathBuf}; - -use tracing::warn; +use std::path::PathBuf; use crate::project::Project; -#[derive(Debug)] -pub struct NotMatched; +pub trait Parser { + type Error: std::error::Error; -impl Display for NotMatched { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Failed to parse path") - } + fn parse(&self, path_buf: PathBuf) -> Result<Project, Self::Error>; } -impl std::error::Error for NotMatched {} +pub trait FilterMap { + fn filter_map(&self, path_buf: PathBuf) -> Option<Project>; +} -pub trait Parser { - fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>>; +impl<T> FilterMap for T +where + T: Parser, +{ + fn filter_map(&self, path_buf: PathBuf) -> Option<Project> { + match self.parse(path_buf) { + Ok(p) => Some(p), + Err(err) => { + tracing::info!(%err, "Parser failed to parse project"); + None + } + } + } } -impl Parser for Vec<Box<dyn Parser>> { - fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> { +impl FilterMap for Vec<Box<dyn FilterMap>> { + fn filter_map(&self, path_buf: PathBuf) -> Option<Project> { self.iter() - .map(|p| p.parse(path_buf.to_owned())) - .inspect(|res| { - if let Err(err) = res { - warn!(%err, "Parser failed to match"); - } - }) - .flatten() + .filter_map(|p| p.filter_map(path_buf.to_owned())) .reduce(|max, p| p.max(max)) - .ok_or(Box::new(NotMatched)) } } |