aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs45
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))
}
}