add a map() method on the Parser trait

This commit is contained in:
Geoffroy Couprie 2020-04-10 10:54:12 +02:00
parent 4cfe336b48
commit ac34e5ac11

View File

@ -167,6 +167,17 @@ pub trait Parser<I, O, E> {
/// a parser takes in input type, and returns a `Result` containing
/// either the remaining input and the output value, or an error
fn parse(&mut self, input: I) -> IResult<I, O, E>;
/// maps a function over the result of a parser
fn map<G,O2>(self, g: G) -> Mapper<Self, G, O>
where G: Fn(O) -> O2,
Self: std::marker::Sized, {
Mapper {
f: self,
g,
phantom: std::marker::PhantomData,
}
}
}
impl<'a, I, O, E, F> Parser<I, O, E> for F
@ -178,6 +189,23 @@ where
}
}
/// implementation of parser mapping
pub struct Mapper<F, G, O1> {
f: F,
g: G,
phantom: std::marker::PhantomData<O1>,
}
impl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Fn(O1) -> O2> Parser<I, O2, E> for Mapper<F, G, O1>
{
fn parse(&mut self, i: I) -> IResult<I, O2, E> {
match self.f.parse(i) {
Err(e) => Err(e),
Ok((i, o)) => Ok((i, (self.g)(o))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;