74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
use crate::{annotated::AnnotatedParser, map, seq2, surrounded_by};
|
|
|
|
pub type ParseResult<I, O, E> = Result<(O, I), (E, I)>;
|
|
|
|
pub trait Parser<I, O, E> {
|
|
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
|
fn name(&self) -> Option<String> {
|
|
None
|
|
}
|
|
}
|
|
|
|
impl<I, O, E, F> Parser<I, O, E> for F
|
|
where
|
|
F: Fn(I) -> ParseResult<I, O, E>,
|
|
{
|
|
fn parse(&self, input: I) -> ParseResult<I, O, E> {
|
|
self(input)
|
|
}
|
|
}
|
|
|
|
pub trait ParserExtension<I, O, E>: Parser<I, O, E> {
|
|
fn map<F, O2>(self, map_fn: F) -> impl Parser<I, O2, E>
|
|
where
|
|
F: Fn(O) -> O2;
|
|
|
|
fn to<O2: Clone>(self, item: O2) -> impl Parser<I, O2, E>;
|
|
fn then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, (O, O2), E>;
|
|
fn then_ignore<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O, E>;
|
|
fn ignore_then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O2, E>;
|
|
fn surrounded_by<O2>(self, surrounding: impl Parser<I, O2, E>) -> impl Parser<I, O, E>;
|
|
fn to_anno(self) -> AnnotatedParser<Self, I, O, E>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
AnnotatedParser::new(self)
|
|
}
|
|
fn to_named(self, name: &str) -> AnnotatedParser<Self, I, O, E>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
AnnotatedParser::new(self).with_name(name)
|
|
}
|
|
}
|
|
|
|
impl<T, I, O, E> ParserExtension<I, O, E> for T
|
|
where
|
|
T: Parser<I, O, E>,
|
|
{
|
|
fn map<F, O2>(self, map_fn: F) -> impl Parser<I, O2, E>
|
|
where
|
|
F: Fn(O) -> O2,
|
|
{
|
|
map(self, map_fn)
|
|
}
|
|
|
|
fn to<O2: Clone>(self, item: O2) -> impl Parser<I, O2, E> {
|
|
self.map(move |_| item.clone())
|
|
}
|
|
|
|
fn then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, (O, O2), E> {
|
|
seq2(self, next)
|
|
}
|
|
|
|
fn then_ignore<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O, E> {
|
|
seq2(self, next).map(|(this, _)| this)
|
|
}
|
|
fn ignore_then<O2, P: Parser<I, O2, E>>(self, next: P) -> impl Parser<I, O2, E> {
|
|
seq2(self, next).map(|(_, next)| next)
|
|
}
|
|
fn surrounded_by<O2>(self, surrounding: impl Parser<I, O2, E>) -> impl Parser<I, O, E> {
|
|
surrounded_by(self, surrounding)
|
|
}
|
|
}
|