From fec7d51f75d7b27455745a5f04812152d3df944c Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 24 Apr 2023 19:18:38 -0400 Subject: [PATCH] Implement radio targets. --- src/parser/radio_link.rs | 41 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/parser/radio_link.rs b/src/parser/radio_link.rs index 8bba782..80b75a6 100644 --- a/src/parser/radio_link.rs +++ b/src/parser/radio_link.rs @@ -1,7 +1,21 @@ +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::character::complete::line_ending; +use nom::character::complete::space0; +use nom::combinator::verify; +use nom::multi::many_till; + use super::Context; use crate::error::CustomError; use crate::error::MyError; use crate::error::Res; +use crate::parser::exiting::ExitClass; +use crate::parser::object_parser::minimal_set_object; +use crate::parser::parser_context::ContextElement; +use crate::parser::parser_context::ExitMatcherNode; +use crate::parser::parser_with_context::parser_with_context; +use crate::parser::util::exit_matcher_parser; +use crate::parser::util::get_consumed; use crate::parser::RadioLink; use crate::parser::RadioTarget; @@ -17,7 +31,28 @@ pub fn radio_target<'r, 's>( context: Context<'r, 's>, input: &'s str, ) -> Res<&'s str, RadioTarget<'s>> { - return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not implemented yet.", - )))); + let (remaining, _opening) = tag("<<<")(input)?; + let parser_context = + context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { + class: ExitClass::Beta, + exit_matcher: &radio_target_end, + })); + + let (remaining, (children, _exit_contents)) = verify( + many_till( + parser_with_context!(minimal_set_object)(&parser_context), + parser_with_context!(exit_matcher_parser)(&parser_context), + ), + |(children, _exit_contents)| !children.is_empty(), + )(remaining)?; + + let (remaining, _closing) = tag(">>>")(remaining)?; + let (remaining, _trailing_whitespace) = space0(remaining)?; + let source = get_consumed(input, remaining); + Ok((remaining, RadioTarget { source, children })) +} + +#[tracing::instrument(ret, level = "debug")] +fn radio_target_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { + alt((tag("<"), tag(">"), line_ending))(input) }