compare_properties example block.
This commit is contained in:
parent
ec98e1c3c5
commit
bdfa050ee3
@ -13,6 +13,10 @@ use super::util::get_property_numeric;
|
|||||||
use super::util::get_property_quoted_string;
|
use super::util::get_property_quoted_string;
|
||||||
use super::util::get_property_unquoted_atom;
|
use super::util::get_property_unquoted_atom;
|
||||||
use crate::types::AstNode;
|
use crate::types::AstNode;
|
||||||
|
use crate::types::CharOffsetInLine;
|
||||||
|
use crate::types::LineNumber;
|
||||||
|
use crate::types::RetainLabels;
|
||||||
|
use crate::types::SwitchNumberLines;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum EmacsField<'s> {
|
pub(crate) enum EmacsField<'s> {
|
||||||
@ -376,3 +380,115 @@ where
|
|||||||
}
|
}
|
||||||
Ok(ComparePropertiesResult::NoChange)
|
Ok(ComparePropertiesResult::NoChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compare_property_number_lines<
|
||||||
|
'b,
|
||||||
|
's,
|
||||||
|
'x,
|
||||||
|
'y,
|
||||||
|
R,
|
||||||
|
RG: Fn(R) -> Option<&'y SwitchNumberLines>,
|
||||||
|
>(
|
||||||
|
_source: &'s str,
|
||||||
|
emacs: &'b Token<'s>,
|
||||||
|
rust_node: R,
|
||||||
|
emacs_field: &'x str,
|
||||||
|
rust_value_getter: RG,
|
||||||
|
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||||
|
let number_lines = get_property(emacs, emacs_field)?;
|
||||||
|
let rust_value = rust_value_getter(rust_node);
|
||||||
|
match (number_lines, &rust_value) {
|
||||||
|
(None, None) => {}
|
||||||
|
(Some(number_lines), Some(rust_number_lines)) => {
|
||||||
|
let token_list = number_lines.as_list()?;
|
||||||
|
let number_type = token_list
|
||||||
|
.get(0)
|
||||||
|
.map(Token::as_atom)
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
|
.ok_or(":number-lines should have a type.")?;
|
||||||
|
let number_value = token_list
|
||||||
|
.get(2)
|
||||||
|
.map(Token::as_atom)
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
|
.map(|val| val.parse::<LineNumber>())
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
|
.ok_or(":number-lines should have a value.")?;
|
||||||
|
match (number_type, number_value, rust_number_lines) {
|
||||||
|
("new", emacs_val, SwitchNumberLines::New(rust_val)) if emacs_val == *rust_val => {}
|
||||||
|
("continued", emacs_val, SwitchNumberLines::Continued(rust_val))
|
||||||
|
if emacs_val == *rust_val => {}
|
||||||
|
_ => {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, number_lines, rust_value
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, number_lines, rust_value
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ComparePropertiesResult::NoChange)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compare_property_retain_labels<'b, 's, 'x, 'y, R, RG: Fn(R) -> &'y RetainLabels>(
|
||||||
|
_source: &'s str,
|
||||||
|
emacs: &'b Token<'s>,
|
||||||
|
rust_node: R,
|
||||||
|
emacs_field: &'x str,
|
||||||
|
rust_value_getter: RG,
|
||||||
|
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error + 's>> {
|
||||||
|
let rust_value = rust_value_getter(rust_node);
|
||||||
|
let retain_labels = get_property_unquoted_atom(emacs, ":retain-labels")?;
|
||||||
|
if let Some(retain_labels) = retain_labels {
|
||||||
|
if retain_labels == "t" {
|
||||||
|
match rust_value {
|
||||||
|
RetainLabels::Yes => {}
|
||||||
|
_ => {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, retain_labels, rust_value
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let retain_labels: CharOffsetInLine = get_property_numeric(emacs, ":retain-labels")?.expect("Cannot be None or else the earlier get_property_unquoted_atom would have been None.");
|
||||||
|
match (retain_labels, rust_value) {
|
||||||
|
(e, RetainLabels::Keep(r)) if e == *r => {}
|
||||||
|
_ => {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, retain_labels, rust_value
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match rust_value {
|
||||||
|
RetainLabels::No => {}
|
||||||
|
_ => {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, retain_labels, rust_value
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ComparePropertiesResult::NoChange)
|
||||||
|
}
|
||||||
|
@ -10,8 +10,10 @@ use super::compare_field::compare_property_always_nil;
|
|||||||
use super::compare_field::compare_property_boolean;
|
use super::compare_field::compare_property_boolean;
|
||||||
use super::compare_field::compare_property_list_of_ast_nodes;
|
use super::compare_field::compare_property_list_of_ast_nodes;
|
||||||
use super::compare_field::compare_property_list_of_quoted_string;
|
use super::compare_field::compare_property_list_of_quoted_string;
|
||||||
|
use super::compare_field::compare_property_number_lines;
|
||||||
use super::compare_field::compare_property_numeric;
|
use super::compare_field::compare_property_numeric;
|
||||||
use super::compare_field::compare_property_quoted_string;
|
use super::compare_field::compare_property_quoted_string;
|
||||||
|
use super::compare_field::compare_property_retain_labels;
|
||||||
use super::compare_field::compare_property_set_of_quoted_string;
|
use super::compare_field::compare_property_set_of_quoted_string;
|
||||||
use super::compare_field::compare_property_single_ast_node;
|
use super::compare_field::compare_property_single_ast_node;
|
||||||
use super::compare_field::compare_property_unquoted_atom;
|
use super::compare_field::compare_property_unquoted_atom;
|
||||||
@ -1944,166 +1946,73 @@ fn compare_comment_block<'b, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn compare_example_block<'b, 's>(
|
fn compare_example_block<'b, 's>(
|
||||||
_source: &'s str,
|
source: &'s str,
|
||||||
emacs: &'b Token<'s>,
|
emacs: &'b Token<'s>,
|
||||||
rust: &'b ExampleBlock<'s>,
|
rust: &'b ExampleBlock<'s>,
|
||||||
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error + 's>> {
|
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error + 's>> {
|
||||||
let mut this_status = DiffStatus::Good;
|
let mut this_status = DiffStatus::Good;
|
||||||
|
let mut child_status = Vec::new();
|
||||||
let mut message = None;
|
let mut message = None;
|
||||||
|
|
||||||
// TODO: Compare :caption
|
assert_no_children(emacs, &mut this_status, &mut message)?;
|
||||||
// Compare name
|
|
||||||
let name = get_property_quoted_string(emacs, ":name")?;
|
|
||||||
if name.as_ref().map(String::as_str) != rust.name {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Name mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
name, rust.name
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare value
|
for diff in compare_properties!(
|
||||||
let contents = get_property_quoted_string(emacs, ":value")?.unwrap_or(String::new());
|
source,
|
||||||
if contents != rust.contents {
|
emacs,
|
||||||
this_status = DiffStatus::Bad;
|
rust,
|
||||||
message = Some(format!(
|
(
|
||||||
"Value mismatch (emacs != rust) {:?} != {:?}",
|
EmacsField::Optional(":name"),
|
||||||
contents, rust.contents
|
|r| r.name,
|
||||||
));
|
compare_property_quoted_string
|
||||||
}
|
),
|
||||||
|
(
|
||||||
// Compare switches
|
EmacsField::Optional(":caption"),
|
||||||
let switches = get_property_quoted_string(emacs, ":switches")?;
|
compare_identity,
|
||||||
match (switches.as_ref().map(String::as_str), rust.switches) {
|
compare_noop
|
||||||
(None, None) => {}
|
),
|
||||||
(Some(""), None) => {}
|
(
|
||||||
(None, Some("")) => {
|
EmacsField::Required(":value"),
|
||||||
unreachable!("The organic parser would return a None instead of an empty string.");
|
|r| Some(r.contents.as_str()),
|
||||||
}
|
compare_property_quoted_string
|
||||||
(Some(e), Some(r)) if e == r => {}
|
),
|
||||||
_ => {
|
(
|
||||||
this_status = DiffStatus::Bad;
|
EmacsField::Required(":switches"),
|
||||||
message = Some(format!(
|
|r| r.switches,
|
||||||
"Switches mismatch (emacs != rust) {:?} != {:?}",
|
compare_property_quoted_string
|
||||||
switches, rust.switches
|
),
|
||||||
));
|
(
|
||||||
}
|
EmacsField::Required(":number-lines"),
|
||||||
}
|
|r| r.number_lines.as_ref(),
|
||||||
|
compare_property_number_lines
|
||||||
// Compare number-lines
|
),
|
||||||
let number_lines = get_property(emacs, ":number-lines")?;
|
(
|
||||||
match (number_lines, &rust.number_lines) {
|
EmacsField::Required(":preserve-indent"),
|
||||||
(None, None) => {}
|
|r| r.preserve_indent,
|
||||||
(Some(number_lines), Some(rust_number_lines)) => {
|
compare_property_numeric
|
||||||
let token_list = number_lines.as_list()?;
|
),
|
||||||
let number_type = token_list
|
(
|
||||||
.get(0)
|
EmacsField::Required(":retain-labels"),
|
||||||
.map(Token::as_atom)
|
|r| &r.retain_labels,
|
||||||
.map_or(Ok(None), |r| r.map(Some))?
|
compare_property_retain_labels
|
||||||
.ok_or(":number-lines should have a type.")?;
|
),
|
||||||
let number_value = token_list
|
(
|
||||||
.get(2)
|
EmacsField::Required(":use-labels"),
|
||||||
.map(Token::as_atom)
|
|r| r.use_labels,
|
||||||
.map_or(Ok(None), |r| r.map(Some))?
|
compare_property_boolean
|
||||||
.map(|val| val.parse::<LineNumber>())
|
),
|
||||||
.map_or(Ok(None), |r| r.map(Some))?
|
(
|
||||||
.ok_or(":number-lines should have a value.")?;
|
EmacsField::Required(":label-fmt"),
|
||||||
match (number_type, number_value, rust_number_lines) {
|
|r| r.label_format,
|
||||||
("new", emacs_val, SwitchNumberLines::New(rust_val)) if emacs_val == *rust_val => {}
|
compare_property_quoted_string
|
||||||
("continued", emacs_val, SwitchNumberLines::Continued(rust_val))
|
)
|
||||||
if emacs_val == *rust_val => {}
|
) {
|
||||||
_ => {
|
match diff {
|
||||||
this_status = DiffStatus::Bad;
|
ComparePropertiesResult::NoChange => {}
|
||||||
message = Some(format!(
|
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||||
"Number lines mismatch (emacs != rust) {:?} != {:?}",
|
this_status = new_status;
|
||||||
number_lines, rust.number_lines
|
message = new_message
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry),
|
||||||
_ => {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Number lines mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
number_lines, rust.number_lines
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compare preserve-indent
|
|
||||||
let preserve_indent: Option<CharOffsetInLine> =
|
|
||||||
get_property_numeric(emacs, ":preserve-indent")?;
|
|
||||||
if preserve_indent != rust.preserve_indent {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Prserve indent mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
preserve_indent, rust.preserve_indent
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare retain-labels
|
|
||||||
// retain-labels is t by default, nil if -r is set, or a number if -k and -r is set.
|
|
||||||
let retain_labels = get_property_unquoted_atom(emacs, ":retain-labels")?;
|
|
||||||
if let Some(retain_labels) = retain_labels {
|
|
||||||
if retain_labels == "t" {
|
|
||||||
match rust.retain_labels {
|
|
||||||
RetainLabels::Yes => {}
|
|
||||||
_ => {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Retain labels mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
retain_labels, rust.retain_labels
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let retain_labels: CharOffsetInLine = get_property_numeric(emacs, ":retain-labels")?.expect("Cannot be None or else the earlier get_property_unquoted_atom would have been None.");
|
|
||||||
match (retain_labels, &rust.retain_labels) {
|
|
||||||
(e, RetainLabels::Keep(r)) if e == *r => {}
|
|
||||||
_ => {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Retain labels mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
retain_labels, rust.retain_labels
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match rust.retain_labels {
|
|
||||||
RetainLabels::No => {}
|
|
||||||
_ => {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Retain labels mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
retain_labels, rust.retain_labels
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare use-labels
|
|
||||||
let use_labels = get_property_boolean(emacs, ":use-labels")?;
|
|
||||||
if use_labels != rust.use_labels {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Use labels mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
use_labels, rust.use_labels
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare label-fmt
|
|
||||||
let label_format = get_property_quoted_string(emacs, ":label-fmt")?;
|
|
||||||
match (label_format.as_ref(), rust.label_format) {
|
|
||||||
(None, None) => {}
|
|
||||||
(Some(emacs_label_format), Some(rust_label_format))
|
|
||||||
if emacs_label_format == rust_label_format => {}
|
|
||||||
_ => {
|
|
||||||
this_status = DiffStatus::Bad;
|
|
||||||
message = Some(format!(
|
|
||||||
"Label format mismatch (emacs != rust) {:?} != {:?}",
|
|
||||||
label_format, rust.label_format
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2111,7 +2020,7 @@ fn compare_example_block<'b, 's>(
|
|||||||
status: this_status,
|
status: this_status,
|
||||||
name: rust.get_elisp_name(),
|
name: rust.get_elisp_name(),
|
||||||
message,
|
message,
|
||||||
children: Vec::new(),
|
children: child_status,
|
||||||
rust_source: rust.get_source(),
|
rust_source: rust.get_source(),
|
||||||
emacs_token: emacs,
|
emacs_token: emacs,
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use nom::combinator::verify;
|
|||||||
use nom::multi::many0;
|
use nom::multi::many0;
|
||||||
use nom::multi::many_till;
|
use nom::multi::many_till;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
use nom::InputTake;
|
||||||
|
|
||||||
use super::keyword::affiliated_keyword;
|
use super::keyword::affiliated_keyword;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
@ -160,7 +161,20 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
|
) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
|
||||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||||
let (remaining, _) = lesser_block_begin("example")(context, remaining)?;
|
let (remaining, _) = lesser_block_begin("example")(context, remaining)?;
|
||||||
let (remaining, parameters) = opt(tuple((space1, example_switches)))(remaining)?;
|
let (remaining, parameters) = opt(alt((
|
||||||
|
map(tuple((space1, example_switches)), |(_, switches)| switches),
|
||||||
|
map(space1, |ws: OrgSource<'_>| {
|
||||||
|
let source = ws.take(0);
|
||||||
|
ExampleSrcSwitches {
|
||||||
|
source: source.into(),
|
||||||
|
number_lines: None,
|
||||||
|
retain_labels: RetainLabels::Yes,
|
||||||
|
preserve_indent: None,
|
||||||
|
use_labels: true,
|
||||||
|
label_format: None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)))(remaining)?;
|
||||||
let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
|
let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
|
||||||
let lesser_block_end_specialized = lesser_block_end("example");
|
let lesser_block_end_specialized = lesser_block_end("example");
|
||||||
let contexts = [
|
let contexts = [
|
||||||
@ -174,7 +188,6 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
|||||||
let parser_context = context.with_additional_node(&contexts[0]);
|
let parser_context = context.with_additional_node(&contexts[0]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||||
let parameters = parameters.map(|(_, parameters)| parameters);
|
|
||||||
|
|
||||||
let (remaining, contents) = content(&parser_context, remaining)?;
|
let (remaining, contents) = content(&parser_context, remaining)?;
|
||||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||||
@ -185,11 +198,7 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
|||||||
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = {
|
||||||
if let Some(parameters) = parameters {
|
if let Some(parameters) = parameters {
|
||||||
(
|
(
|
||||||
if parameters.source.len() == 0 {
|
Some(parameters.source),
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(parameters.source)
|
|
||||||
},
|
|
||||||
parameters.number_lines,
|
parameters.number_lines,
|
||||||
parameters.preserve_indent,
|
parameters.preserve_indent,
|
||||||
parameters.retain_labels,
|
parameters.retain_labels,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user