diff --git a/src/parser.rs b/src/parser.rs index 1bf08ef..3a79563 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,4 @@ -use crate::{map, seq2}; +use crate::{map, seq2, surrounded_by}; pub type ParseResult = Result<(O, I), (E, I)>; @@ -24,6 +24,7 @@ pub trait ParserExtension: Parser { fn then>(self, next: P) -> impl Parser; fn then_ignore>(self, next: P) -> impl Parser; fn ignore_then>(self, next: P) -> impl Parser; + fn surrounded_by(self, surrounding: impl Parser) -> impl Parser; } impl ParserExtension for T @@ -51,4 +52,7 @@ where fn ignore_then>(self, next: P) -> impl Parser { seq2(self, next).map(|(_, next)| next) } + fn surrounded_by(self, surrounding: impl Parser) -> impl Parser { + surrounded_by(self, surrounding) + } } diff --git a/src/sequence.rs b/src/sequence.rs index 23f44df..7fa4aac 100644 --- a/src/sequence.rs +++ b/src/sequence.rs @@ -7,6 +7,18 @@ where move |input| -> ParseResult { sequence.parse(input) } } +pub fn surrounded_by( + main: impl Parser, + surrounding: impl Parser, +) -> impl Parser { + move |input| { + let (_result1, rest1) = surrounding.parse(input)?; + let (result2, rest2) = main.parse(rest1)?; + let (_result3, rest3) = surrounding.parse(rest2)?; + Ok((result2, rest3)) + } +} + pub fn seq2( first: impl Parser, second: impl Parser, @@ -32,3 +44,22 @@ where }) } } + +impl Sequence for (P1, P2, P3) +where + P1: Parser, + P2: Parser, + P3: Parser, +{ + fn parse(&self, input: I) -> ParseResult { + let p1 = &self.0; + let p2 = &self.1; + let p3 = &self.2; + + let (result1, rest1) = p1.parse(input)?; + let (result2, rest2) = p2.parse(rest1)?; + let (result3, rest3) = p3.parse(rest2)?; + + Ok(((result1, result2, result3), rest3)) + } +}