From 9a3745d25c277dd4deb22a96081dc72e272a42a6 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sat, 25 Feb 2023 03:27:32 -0800 Subject: [PATCH] implement representation for json_bool --- src/choice/mod.rs | 51 ++++++++++++++++++++++++++++++++++-- src/parser/representation.rs | 22 ++++++++++++++++ tests/json_parser.rs | 4 +++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/choice/mod.rs b/src/choice/mod.rs index 877c625..46063dd 100644 --- a/src/choice/mod.rs +++ b/src/choice/mod.rs @@ -1,4 +1,4 @@ -use crate::parser::{ParseResult, Parser, ParserInput}; +use crate::parser::{ParseResult, Parser, ParserInput, Representation}; pub fn choice2(parser1: P1, parser2: P2) -> impl Parser where @@ -14,11 +14,13 @@ where C: Choice, I: ParserInput + Clone, { - move |input| choices.parse(input) + let rep = choices.representation(); + (move |input| choices.parse(input), rep) } pub trait Choice { fn parse(&self, input: I) -> ParseResult; + fn representation(&self) -> Representation; } impl Choice for (P1, P2) @@ -31,6 +33,11 @@ where let parsers = vec![&self.0 as &dyn Parser, &self.1]; choice_loop(input, parsers) } + + fn representation(&self) -> Representation { + let parsers = vec![&self.0 as &dyn Parser, &self.1]; + repr_loop(parsers) + } } impl Choice for (P1, P2, P3) @@ -44,6 +51,11 @@ where let parsers = vec![&self.0 as &dyn Parser, &self.1, &self.2]; choice_loop(input, parsers) } + + fn representation(&self) -> Representation { + let parsers = vec![&self.0 as &dyn Parser, &self.1, &self.2]; + repr_loop(parsers) + } } impl Choice for (P1, P2, P3, P4) @@ -58,6 +70,11 @@ where let parsers = vec![&self.0 as &dyn Parser, &self.1, &self.2, &self.3]; choice_loop(input, parsers) } + + fn representation(&self) -> Representation { + let parsers = vec![&self.0 as &dyn Parser, &self.1, &self.2, &self.3]; + repr_loop(parsers) + } } impl Choice for (P1, P2, P3, P4, P5) @@ -79,6 +96,17 @@ where ]; choice_loop(input, parsers) } + + fn representation(&self) -> Representation { + let parsers = vec![ + &self.0 as &dyn Parser, + &self.1, + &self.2, + &self.3, + &self.4, + ]; + repr_loop(parsers) + } } impl Choice for (P1, P2, P3, P4, P5, P6) @@ -102,6 +130,17 @@ where ]; choice_loop(input, parsers) } + fn representation(&self) -> Representation { + let parsers = vec![ + &self.0 as &dyn Parser, + &self.1, + &self.2, + &self.3, + &self.4, + &self.5, + ]; + repr_loop(parsers) + } } fn choice_loop(input: I, parsers: Vec<&dyn Parser>) -> ParseResult @@ -122,6 +161,14 @@ where Err(err.unwrap()) } +fn repr_loop(parsers: Vec<&dyn Parser>) -> Representation +where + I: ParserInput + Clone, +{ + let mut iter = parsers.iter().map(|p| p.representation()); + Representation::from_choice(&mut iter) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/parser/representation.rs b/src/parser/representation.rs index f94dd24..cc88680 100644 --- a/src/parser/representation.rs +++ b/src/parser/representation.rs @@ -9,4 +9,26 @@ impl Representation { val: from.to_string(), } } + + pub fn from_choice(choice_parser_reps: &mut impl Iterator) -> Self { + let mut buf = String::new(); + let mut iter = choice_parser_reps.peekable(); + loop { + let rep = match iter.next() { + Some(r) => r, + None => break, + }; + buf.push_str(&rep.val); + match iter.peek() { + Some(_) => { + buf.push_str(" | "); + } + None => { + break; + } + } + } + + Representation::new(&buf) + } } diff --git a/tests/json_parser.rs b/tests/json_parser.rs index 7732422..f57daa7 100644 --- a/tests/json_parser.rs +++ b/tests/json_parser.rs @@ -240,4 +240,8 @@ fn parse_json_document() { #[test] fn test_representations() { assert_eq!(json_null().representation(), Representation::new("null")); + assert_eq!( + json_bool().representation(), + Representation::new("true | false") + ); }