diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 426f42e0..c08e559a 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; -// TODO: Add a check for unexpected keys in the properties +// TODO: Update all to use the macro to assert there are no unexpected keys. +// TODO: Check all compare funtions for whether they correctly iterate children. use std::collections::BTreeSet; use std::collections::HashSet; @@ -2893,14 +2894,31 @@ fn compare_radio_link<'b, 's>( } fn compare_radio_target<'b, 's>( - _source: &'s str, + source: &'s str, emacs: &'b Token<'s>, rust: &'b RadioTarget<'s>, ) -> Result, Box> { - let this_status = DiffStatus::Good; - let message = None; + let children = emacs.as_list()?; + let mut this_status = DiffStatus::Good; + let mut child_status = Vec::new(); + let mut message = None; - // TODO: Compare :value + if let Some((new_status, new_message)) = compare_properties!( + emacs, + rust, + ( + EmacsField::Required(":value"), + |r| Some(r.value), + compare_property_quoted_string + ) + )? { + this_status = new_status; + message = new_message; + } + + for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); + } Ok(DiffResult { status: this_status, diff --git a/src/parser/radio_link.rs b/src/parser/radio_link.rs index c5a4ac4e..5edd8b6f 100644 --- a/src/parser/radio_link.rs +++ b/src/parser/radio_link.rs @@ -2,6 +2,8 @@ use nom::branch::alt; use nom::bytes::complete::tag; use nom::character::complete::line_ending; use nom::character::complete::space0; +use nom::combinator::consumed; +use nom::combinator::map; use nom::combinator::verify; use nom::multi::many_till; @@ -108,13 +110,16 @@ pub(crate) fn radio_target<'b, 'g, 'r, 's>( }); let parser_context = context.with_additional_node(&parser_context); - let (remaining, (children, _exit_contents)) = verify( - many_till( - parser_with_context!(minimal_set_object)(&parser_context), - parser_with_context!(exit_matcher_parser)(&parser_context), + let (remaining, (raw_value, children)) = consumed(verify( + map( + many_till( + parser_with_context!(minimal_set_object)(&parser_context), + parser_with_context!(exit_matcher_parser)(&parser_context), + ), + |(children, _)| children, ), - |(children, _exit_contents)| !children.is_empty(), - )(remaining)?; + |children: &Vec<_>| !children.is_empty(), + ))(remaining)?; let (remaining, _closing) = tag(">>>")(remaining)?; let (remaining, _trailing_whitespace) = @@ -124,6 +129,7 @@ pub(crate) fn radio_target<'b, 'g, 'r, 's>( remaining, RadioTarget { source: source.into(), + value: raw_value.into(), children, }, )) diff --git a/src/types/object.rs b/src/types/object.rs index a177d417..ea884f04 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -90,14 +90,15 @@ pub struct RegularLink<'s> { #[derive(Debug, PartialEq)] pub struct RadioTarget<'s> { pub source: &'s str, + pub value: &'s str, pub children: Vec>, } #[derive(Debug, PartialEq)] pub struct RadioLink<'s> { pub source: &'s str, - pub path: Cow<'s, str>, - pub raw_link: Cow<'s, str>, + pub path: &'s str, + pub raw_link: &'s str, // TODO: Is this always the same as path? If so, this could be a function instead of a field. pub children: Vec>, }