diff options
author | Toby Vincent <tobyv13@gmail.com> | 2023-05-04 19:43:08 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2023-05-04 19:43:08 -0500 |
commit | 5da4fb25f9bb72771c7f2798daa6339be0bc3900 (patch) | |
tree | c30639c7a95e1d94baff498d247eed43fdb3728e /src/parser.rs | |
parent | 589cd987217755e1da7acbc304c373a75a9f7db5 (diff) |
refactor: join iterators into a single walk
Diffstat (limited to 'src/parser.rs')
-rw-r--r-- | src/parser.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 0000000..1d3f159 --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,35 @@ +use std::{fmt::Display, path::PathBuf}; + +use tracing::warn; + +use crate::project::Project; + +#[derive(Debug)] +pub struct NotMatched; + +impl Display for NotMatched { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Failed to parse path") + } +} + +impl std::error::Error for NotMatched {} + +pub trait Parser { + fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>>; +} + +impl Parser for Vec<Box<dyn Parser>> { + fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> { + self.iter() + .map(|p| p.parse(path_buf.to_owned())) + .inspect(|res| { + if let Err(err) = res { + warn!(%err, "Parser failed to match"); + } + }) + .flatten() + .reduce(|max, p| p.max(max)) + .ok_or(Box::new(NotMatched)) + } +} |