From e697b8ed21c176370985d702bc662cf3ee24ad96 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Fri, 26 Jan 2024 09:39:46 -0800 Subject: [PATCH] Sequence trait --- src/lib.rs | 10 +++++----- src/sequence.rs | 30 +++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ad50a6b..41eb741 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,7 @@ mod tests { #[test] fn test_sequence() { - let parser = sequence(literal("bongo"), sequence(literal(" "), literal("jonzzz"))); + let parser = seq2(literal("bongo"), seq2(literal(" "), literal("jonzzz"))); let output = parser.parse("bongo jonzzz").unwrap(); assert_eq!(output.0 .0, "bongo"); assert_eq!(output.0 .1, (" ", "jonzzz")); @@ -61,7 +61,7 @@ mod tests { #[test] fn test_map() { let parser = map( - sequence(literal("a"), literal("b")), + seq2(literal("a"), literal("b")), |(_a, _b): (&str, &str)| 59, ); let output = parser.parse("abcd").unwrap(); @@ -70,16 +70,16 @@ mod tests { #[test] fn test_combinators() { - let parser = sequence(map(repeated(literal_char('a')), |_| 10), literal_char('b')); + let parser = seq2(map(repeated(literal_char('a')), |_| 10), literal_char('b')); let output = parser.parse("aaaaaaaabcd").unwrap(); assert_eq! {((10, 'b'), "cd"), output}; } #[test] fn test_optional() { - let parser = sequence( + let parser = seq2( optional(literal("alpha")), - sequence(repeated(literal(" ")), literal("beta")), + seq2(repeated(literal(" ")), literal("beta")), ); let output1 = parser.parse(" beta").unwrap(); diff --git a/src/sequence.rs b/src/sequence.rs index 87229e1..23f44df 100644 --- a/src/sequence.rs +++ b/src/sequence.rs @@ -1,13 +1,33 @@ use crate::{ParseResult, Parser}; -pub fn sequence( +pub fn sequence(sequence: S) -> impl Parser +where + S: Sequence, +{ + move |input| -> ParseResult { sequence.parse(input) } +} + +pub fn seq2( first: impl Parser, second: impl Parser, ) -> impl Parser { - move |input| -> ParseResult { - first.parse(input).and_then(|(result1, rest)| { - second - .parse(rest) + sequence((first, second)) +} + +pub trait Sequence { + fn parse(&self, input: I) -> ParseResult; +} + +impl Sequence for (P1, P2) +where + P1: Parser, + P2: Parser, +{ + fn parse(&self, input: I) -> ParseResult { + let p1 = &self.0; + let p2 = &self.1; + p1.parse(input).and_then(|(result1, rest)| { + p2.parse(rest) .map(|(result2, rest2)| ((result1, result2), rest2)) }) }