use crate::{
parser::combinators::{Filter, MapWithDbAndEntry},
Die, DwarfDb,
};
pub mod btreemap;
pub mod children;
pub mod combinators;
pub mod enums;
pub mod functions;
pub mod hashmap;
pub mod option;
pub mod pointers;
pub mod primitives;
pub mod result;
pub mod vec;
use combinators::{And, Context, Map, MapRes, Then};
pub type Result<T> = anyhow::Result<T>;
pub trait Parser<'db, T> {
fn parse(&self, db: &'db dyn DwarfDb, entry: Die<'db>) -> Result<T>;
fn and<U, P>(self, other: P) -> And<Self, P, T, U>
where
Self: Sized,
P: Parser<'db, U>,
{
And {
first: self,
second: other,
_marker: std::marker::PhantomData,
}
}
fn filter(self) -> Filter<Self>
where
Self: Sized,
{
Filter { parser: self }
}
fn map<U, F>(self, f: F) -> Map<Self, F, T>
where
Self: Sized,
F: Fn(T) -> U,
{
Map {
parser: self,
f,
_marker: std::marker::PhantomData,
}
}
fn map_with_db_and_entry<U, F>(self, f: F) -> MapWithDbAndEntry<Self, F, T>
where
Self: Sized,
F: Fn(&'db dyn DwarfDb, Die<'db>, T) -> U,
{
MapWithDbAndEntry {
parser: self,
f,
_marker: std::marker::PhantomData,
}
}
fn map_res<U, F>(self, f: F) -> MapRes<Self, F, T>
where
Self: Sized,
F: Fn(T) -> Result<U>,
{
MapRes {
parser: self,
f,
_marker: std::marker::PhantomData,
}
}
fn then<U, P, V>(self, next: P) -> Then<Self, P, V>
where
Self: Sized + Parser<'db, V>,
P: Parser<'db, U>,
{
Then {
first: self,
second: next,
_marker: std::marker::PhantomData,
}
}
fn context<S: Into<String>>(self, ctx: S) -> Context<Self>
where
Self: Sized,
{
Context {
parser: self,
context: ctx.into(),
}
}
}
impl<'db, T, P> Parser<'db, T> for &'_ P
where
P: Parser<'db, T>,
{
fn parse(&self, db: &'db dyn DwarfDb, entry: Die<'db>) -> Result<T> {
<P as Parser<'db, T>>::parse(self, db, entry)
}
}
pub struct FromFn<F> {
f: F,
}
pub fn from_fn<F>(f: F) -> FromFn<F> {
FromFn { f }
}
impl<'db, T, F, E> Parser<'db, T> for FromFn<F>
where
F: Fn(&'db dyn DwarfDb, Die<'db>) -> std::result::Result<T, E>,
E: Into<anyhow::Error>,
{
fn parse(&self, db: &'db dyn DwarfDb, entry: Die<'db>) -> Result<T> {
(self.f)(db, entry).map_err(Into::into)
}
}