diff --git a/src/choice.rs b/src/choice.rs new file mode 100644 index 0000000..f0ca4cf --- /dev/null +++ b/src/choice.rs @@ -0,0 +1,26 @@ +use crate::parser::Parser; + +pub fn choice(parser1: P1, parser2: P2) -> impl Parser +where + P1: Parser, + P2: Parser, + I: Copy, +{ + move |input| match parser1.parse(input) { + ok @ Ok(..) => ok, + Err(_e) => parser2.parse(input), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::combinators::one_or_more; + use crate::primitives::literal; + + #[test] + fn test_choice() { + let p = choice(literal("gnostika").to(1), one_or_more(literal(" ")).to(2)); + assert_eq!(p.parse("gnostika twentynine"), Ok((1, " twentynine"))); + } +} diff --git a/src/lib.rs b/src/lib.rs index 138ffdf..978d26b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,43 +1,24 @@ -#![feature(assert_matches)] #![allow(dead_code)] //TODO eventually turn this off mod bnf; +mod choice; mod combinators; mod parser; mod primitives; mod sequence; -use parser::{ParseResult, Parser}; - -fn choice(parser1: P1, parser2: P2) -> impl Parser -where - P1: Parser, - P2: Parser, - I: Copy, -{ - move |input| match parser1.parse(input) { - ok @ Ok(..) => ok, - Err(_e) => parser2.parse(input), - } -} +pub use parser::{ParseResult, Parser}; #[cfg(test)] mod tests { use super::*; - use crate::combinators::one_or_more; + use crate::choice::choice; use crate::primitives::literal; - use std::assert_matches::assert_matches; use std::collections::HashMap; #[test] fn test_parsing() { let output = literal("a")("a yolo"); - assert_matches!(output.unwrap(), ("a", " yolo")); - } - - #[test] - fn test_choice() { - let p = choice(literal("gnostika").to(1), one_or_more(literal(" ")).to(2)); - assert_eq!(p.parse("gnostika twentynine"), Ok((1, " twentynine"))); + assert_eq!(output.unwrap(), ("a", " yolo")); } /* @@ -48,7 +29,7 @@ mod tests { ::= "{" [] {"," }* "}" ::= ":" */ - #[derive(Debug, Clone)] + #[derive(Debug, Clone, PartialEq)] enum JsonValue { Null, Bool(bool), @@ -66,6 +47,6 @@ mod tests { let json_value = choice(json_null, choice(json_true, json_false)); - assert_matches!(json_value.parse("true"), Ok((JsonValue::Bool(true), ""))); + assert_eq!(json_value.parse("true"), Ok((JsonValue::Bool(true), ""))); } } diff --git a/src/sequence.rs b/src/sequence.rs index 809726c..cba5a77 100644 --- a/src/sequence.rs +++ b/src/sequence.rs @@ -112,15 +112,16 @@ mod test { use super::*; use crate::combinators::zero_or_more; use crate::primitives::{identifier, literal}; - use std::assert_matches::assert_matches; #[test] fn test_tuple2() { let p = tuple2(identifier, tuple2(literal(" "), literal("ruts"))); - assert_matches!(p.parse("fort1 ruts"), Ok((r, "")) if r.0 == "fort1" && r.1 == (" ", "ruts") ); + let (output, _rest) = p.parse("fort1 ruts").unwrap(); + assert_eq!(output, ("fort1".into(), (" ", "ruts"))); let p = identifier.then(literal(" ")).then(literal("ruts")); - assert_matches!(p.parse("fort1 ruts"), Ok((r, "")) if r.0.0 == "fort1" && r.0.1== " " && r.1 == "ruts"); + let (output, _rest) = p.parse("fort1 ruts").unwrap(); + assert_eq!(output, (("fort1".into(), " "), "ruts")); } #[test]