2023-09-23 21:03:12 -04:00
use std ::borrow ::Cow ;
2023-10-07 01:24:32 -04:00
// 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.
2023-09-08 23:05:04 -04:00
use std ::collections ::BTreeSet ;
2023-08-25 06:46:00 -04:00
use std ::collections ::HashSet ;
2023-10-06 16:42:31 -04:00
use super ::compare_field ::compare_identity ;
2023-10-08 17:24:03 -04:00
use super ::compare_field ::compare_noop ;
2023-10-06 18:30:08 -04:00
use super ::compare_field ::compare_property_always_nil ;
2023-10-08 18:14:48 -04:00
use super ::compare_field ::compare_property_boolean ;
2023-10-09 15:13:05 -04:00
use super ::compare_field ::compare_property_list_of_ast_nodes ;
2023-10-08 14:40:01 -04:00
use super ::compare_field ::compare_property_list_of_quoted_string ;
2023-10-09 21:04:41 -04:00
use super ::compare_field ::compare_property_numeric ;
2023-10-06 16:03:41 -04:00
use super ::compare_field ::compare_property_quoted_string ;
2023-10-09 21:27:18 -04:00
use super ::compare_field ::compare_property_single_ast_node ;
2023-10-06 18:30:08 -04:00
use super ::compare_field ::compare_property_unquoted_atom ;
2023-09-23 21:03:12 -04:00
use super ::elisp_fact ::ElispFact ;
use super ::elisp_fact ::GetElispFact ;
2023-09-11 15:31:48 -04:00
use super ::sexp ::unquote ;
use super ::sexp ::Token ;
2023-10-09 13:00:47 -04:00
use super ::util ::assert_no_children ;
use super ::util ::compare_children ;
2023-09-23 21:03:12 -04:00
use super ::util ::compare_standard_properties ;
2023-08-29 22:07:23 -04:00
use super ::util ::get_property ;
2023-10-02 10:48:34 -04:00
use super ::util ::get_property_boolean ;
2023-10-02 15:49:51 -04:00
use super ::util ::get_property_numeric ;
2023-09-29 17:28:50 -04:00
use super ::util ::get_property_quoted_string ;
2023-09-29 13:03:01 -04:00
use super ::util ::get_property_unquoted_atom ;
2023-10-09 15:13:05 -04:00
use crate ::compare ::compare_field ::ComparePropertiesResult ;
2023-10-06 13:40:11 -04:00
use crate ::compare ::compare_field ::EmacsField ;
2023-10-06 13:08:15 -04:00
use crate ::compare ::macros ::compare_properties ;
2023-09-03 12:52:09 -04:00
use crate ::types ::AngleLink ;
2023-10-02 13:33:00 -04:00
use crate ::types ::AstNode ;
2023-09-23 21:03:12 -04:00
use crate ::types ::BabelCall ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Bold ;
2023-10-02 22:21:24 -04:00
use crate ::types ::CenterBlock ;
2023-10-04 15:20:57 -04:00
use crate ::types ::CharOffsetInLine ;
2023-09-15 15:30:13 -04:00
use crate ::types ::CheckboxType ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Citation ;
use crate ::types ::CitationReference ;
use crate ::types ::Clock ;
2023-10-05 03:19:17 -04:00
use crate ::types ::ClockStatus ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Code ;
use crate ::types ::Comment ;
use crate ::types ::CommentBlock ;
2023-10-02 15:59:06 -04:00
use crate ::types ::Date ;
use crate ::types ::DayOfMonth ;
use crate ::types ::DayOfMonthInner ;
2023-09-03 12:52:09 -04:00
use crate ::types ::DiarySexp ;
use crate ::types ::Document ;
use crate ::types ::DocumentElement ;
use crate ::types ::Drawer ;
use crate ::types ::DynamicBlock ;
use crate ::types ::Entity ;
use crate ::types ::ExampleBlock ;
use crate ::types ::ExportBlock ;
use crate ::types ::ExportSnippet ;
use crate ::types ::FixedWidthArea ;
use crate ::types ::FootnoteDefinition ;
use crate ::types ::FootnoteReference ;
2023-10-09 13:23:08 -04:00
use crate ::types ::FootnoteReferenceType ;
2023-09-23 19:13:01 -04:00
use crate ::types ::GetStandardProperties ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Heading ;
use crate ::types ::HorizontalRule ;
2023-10-02 16:37:23 -04:00
use crate ::types ::Hour ;
2023-10-02 16:32:33 -04:00
use crate ::types ::HourInner ;
2023-09-03 12:52:09 -04:00
use crate ::types ::InlineBabelCall ;
use crate ::types ::InlineSourceBlock ;
use crate ::types ::Italic ;
use crate ::types ::Keyword ;
use crate ::types ::LatexEnvironment ;
use crate ::types ::LatexFragment ;
use crate ::types ::LineBreak ;
2023-10-04 10:31:01 -04:00
use crate ::types ::LineNumber ;
2023-10-06 17:28:26 -04:00
use crate ::types ::LinkType ;
2023-10-02 16:37:23 -04:00
use crate ::types ::Minute ;
2023-10-02 16:32:33 -04:00
use crate ::types ::MinuteInner ;
2023-10-02 15:59:06 -04:00
use crate ::types ::Month ;
use crate ::types ::MonthInner ;
2023-09-06 18:49:59 -04:00
use crate ::types ::NodeProperty ;
2023-09-03 12:52:09 -04:00
use crate ::types ::OrgMacro ;
use crate ::types ::Paragraph ;
use crate ::types ::PlainLink ;
use crate ::types ::PlainList ;
use crate ::types ::PlainListItem ;
2023-09-29 13:03:01 -04:00
use crate ::types ::PlainListType ;
2023-09-03 12:52:09 -04:00
use crate ::types ::PlainText ;
use crate ::types ::Planning ;
2023-09-08 15:57:24 -04:00
use crate ::types ::PriorityCookie ;
2023-09-03 12:52:09 -04:00
use crate ::types ::PropertyDrawer ;
2023-10-02 22:21:24 -04:00
use crate ::types ::QuoteBlock ;
2023-09-03 12:52:09 -04:00
use crate ::types ::RadioLink ;
use crate ::types ::RadioTarget ;
use crate ::types ::RegularLink ;
2023-10-02 18:58:30 -04:00
use crate ::types ::RepeaterType ;
use crate ::types ::RepeaterWarningDelayValueType ;
2023-10-04 15:43:09 -04:00
use crate ::types ::RetainLabels ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Section ;
2023-10-02 22:21:24 -04:00
use crate ::types ::SpecialBlock ;
2023-09-03 12:52:09 -04:00
use crate ::types ::SrcBlock ;
2023-09-23 19:13:01 -04:00
use crate ::types ::StandardProperties ;
2023-09-03 12:52:09 -04:00
use crate ::types ::StatisticsCookie ;
use crate ::types ::StrikeThrough ;
use crate ::types ::Subscript ;
use crate ::types ::Superscript ;
2023-10-04 10:31:01 -04:00
use crate ::types ::SwitchNumberLines ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Table ;
use crate ::types ::TableCell ;
use crate ::types ::TableRow ;
2023-10-03 00:03:58 -04:00
use crate ::types ::TableRowType ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Target ;
2023-10-02 16:37:23 -04:00
use crate ::types ::Time ;
2023-10-02 18:58:30 -04:00
use crate ::types ::TimeUnit ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Timestamp ;
2023-10-02 13:42:46 -04:00
use crate ::types ::TimestampRangeType ;
2023-10-02 13:33:00 -04:00
use crate ::types ::TimestampType ;
2023-09-06 12:39:03 -04:00
use crate ::types ::TodoKeywordType ;
2023-09-03 12:52:09 -04:00
use crate ::types ::Underline ;
use crate ::types ::Verbatim ;
use crate ::types ::VerseBlock ;
2023-10-02 18:58:30 -04:00
use crate ::types ::WarningDelayType ;
2023-10-02 15:59:06 -04:00
use crate ::types ::Year ;
use crate ::types ::YearInner ;
2023-04-11 17:35:09 -04:00
2023-08-29 22:47:40 -04:00
#[ derive(Debug) ]
2023-10-02 12:28:48 -04:00
pub enum DiffEntry < ' b , ' s > {
DiffResult ( DiffResult < ' b , ' s > ) ,
DiffLayer ( DiffLayer < ' b , ' s > ) ,
2023-08-29 22:47:40 -04:00
}
2023-04-11 18:27:01 -04:00
#[ derive(Debug) ]
2023-10-02 12:28:48 -04:00
pub struct DiffResult < ' b , ' s > {
2023-04-11 18:27:01 -04:00
status : DiffStatus ,
2023-09-23 21:03:12 -04:00
name : Cow < ' s , str > ,
2023-04-19 15:19:21 -04:00
message : Option < String > ,
2023-10-02 12:28:48 -04:00
children : Vec < DiffEntry < ' b , ' s > > ,
2023-08-29 14:40:58 -04:00
rust_source : & ' s str ,
#[ allow(dead_code) ]
2023-10-02 12:28:48 -04:00
emacs_token : & ' b Token < ' s > ,
2023-04-11 18:27:01 -04:00
}
2023-04-11 19:22:42 -04:00
#[ derive(Debug, PartialEq) ]
2023-10-06 13:40:11 -04:00
pub ( crate ) enum DiffStatus {
2023-04-11 18:27:01 -04:00
Good ,
Bad ,
}
2023-08-29 22:47:40 -04:00
#[ derive(Debug) ]
2023-10-02 12:28:48 -04:00
pub struct DiffLayer < ' b , ' s > {
2023-09-23 21:03:12 -04:00
name : Cow < ' s , str > ,
2023-10-02 12:28:48 -04:00
children : Vec < DiffEntry < ' b , ' s > > ,
2023-08-29 22:47:40 -04:00
}
2023-10-02 12:28:48 -04:00
impl < ' b , ' s > From < DiffResult < ' b , ' s > > for DiffEntry < ' b , ' s > {
fn from ( value : DiffResult < ' b , ' s > ) -> Self {
2023-08-29 22:47:40 -04:00
DiffEntry ::DiffResult ( value )
}
}
2023-10-02 12:28:48 -04:00
impl < ' b , ' s > From < DiffLayer < ' b , ' s > > for DiffEntry < ' b , ' s > {
fn from ( value : DiffLayer < ' b , ' s > ) -> Self {
2023-08-29 22:47:40 -04:00
DiffEntry ::DiffLayer ( value )
}
}
2023-10-02 12:28:48 -04:00
impl < ' b , ' s > DiffEntry < ' b , ' s > {
2023-08-29 22:47:40 -04:00
fn has_bad_children ( & self ) -> bool {
match self {
DiffEntry ::DiffResult ( diff ) = > & diff . children ,
DiffEntry ::DiffLayer ( diff ) = > & diff . children ,
}
. iter ( )
. any ( | child | child . is_immediately_bad ( ) | | child . has_bad_children ( ) )
}
fn is_immediately_bad ( & self ) -> bool {
match self {
DiffEntry ::DiffResult ( diff ) = > diff . status = = DiffStatus ::Bad ,
DiffEntry ::DiffLayer ( _ ) = > false ,
}
}
2023-09-11 13:13:28 -04:00
pub fn is_bad ( & self ) -> bool {
2023-08-29 22:47:40 -04:00
self . is_immediately_bad ( ) | | self . has_bad_children ( )
}
2023-09-11 13:13:28 -04:00
pub fn print ( & self , original_document : & str ) -> Result < ( ) , Box < dyn std ::error ::Error > > {
2023-08-29 14:40:58 -04:00
self . print_indented ( 0 , original_document )
2023-04-11 18:27:01 -04:00
}
2023-08-29 22:47:40 -04:00
fn print_indented (
& self ,
indentation : usize ,
original_document : & str ,
) -> Result < ( ) , Box < dyn std ::error ::Error > > {
match self {
DiffEntry ::DiffResult ( diff ) = > diff . print_indented ( indentation , original_document ) ,
DiffEntry ::DiffLayer ( diff ) = > diff . print_indented ( indentation , original_document ) ,
}
}
}
2023-10-02 12:28:48 -04:00
impl < ' b , ' s > DiffResult < ' b , ' s > {
2023-08-29 14:40:58 -04:00
fn print_indented (
& self ,
indentation : usize ,
original_document : & str ,
) -> Result < ( ) , Box < dyn std ::error ::Error > > {
2023-04-11 19:22:42 -04:00
let status_text = {
match self . status {
DiffStatus ::Good = > {
if self . has_bad_children ( ) {
2023-08-25 04:09:52 -04:00
format! (
" {color}BADCHILD{reset} " ,
color = DiffResult ::foreground_color ( 255 , 255 , 0 ) ,
reset = DiffResult ::reset_color ( ) ,
)
2023-04-11 19:22:42 -04:00
} else {
2023-08-25 04:09:52 -04:00
format! (
" {color}GOOD{reset} " ,
color = DiffResult ::foreground_color ( 0 , 255 , 0 ) ,
reset = DiffResult ::reset_color ( ) ,
)
2023-04-11 19:22:42 -04:00
}
2023-04-12 11:35:02 -04:00
}
2023-08-25 04:09:52 -04:00
DiffStatus ::Bad = > format! (
" {color}BAD{reset} " ,
color = DiffResult ::foreground_color ( 255 , 0 , 0 ) ,
reset = DiffResult ::reset_color ( ) ,
) ,
2023-04-11 19:22:42 -04:00
}
} ;
2023-08-29 14:40:58 -04:00
let rust_offset = self . rust_source . as_ptr ( ) as usize - original_document . as_ptr ( ) as usize ;
2023-08-29 21:49:16 -04:00
let preceding_text = & original_document [ .. rust_offset ] ;
2023-04-22 17:58:16 -04:00
println! (
2023-08-29 14:40:58 -04:00
" {indentation}{status_text} {name} char({char_offset}) {message} " ,
indentation = " " . repeat ( indentation ) ,
status_text = status_text ,
name = self . name ,
2023-08-29 21:49:16 -04:00
char_offset = preceding_text . chars ( ) . count ( ) + 1 ,
2023-08-29 14:40:58 -04:00
message = self . message . as_ref ( ) . map ( | m | m . as_str ( ) ) . unwrap_or ( " " )
2023-04-22 17:58:16 -04:00
) ;
2023-04-11 18:27:01 -04:00
for child in self . children . iter ( ) {
2023-08-29 14:40:58 -04:00
child . print_indented ( indentation + 1 , original_document ) ? ;
2023-04-11 18:27:01 -04:00
}
Ok ( ( ) )
}
2023-04-11 19:22:42 -04:00
2023-08-29 22:47:40 -04:00
fn has_bad_children ( & self ) -> bool {
2023-04-12 11:35:02 -04:00
self . children
. iter ( )
2023-08-29 22:47:40 -04:00
. any ( | child | child . is_immediately_bad ( ) | | child . has_bad_children ( ) )
2023-04-12 14:50:56 -04:00
}
2023-08-25 04:09:52 -04:00
2023-10-04 18:57:51 -04:00
pub ( crate ) fn foreground_color ( red : u8 , green : u8 , blue : u8 ) -> String {
2023-08-25 04:25:39 -04:00
if DiffResult ::should_use_color ( ) {
format! (
" \x1b [38;2;{red};{green};{blue}m " ,
red = red ,
green = green ,
blue = blue
)
} else {
String ::new ( )
}
2023-08-25 04:09:52 -04:00
}
#[ allow(dead_code) ]
2023-10-04 18:57:51 -04:00
pub ( crate ) fn background_color ( red : u8 , green : u8 , blue : u8 ) -> String {
2023-08-25 04:25:39 -04:00
if DiffResult ::should_use_color ( ) {
format! (
" \x1b [48;2;{red};{green};{blue}m " ,
red = red ,
green = green ,
blue = blue
)
} else {
String ::new ( )
}
2023-08-25 04:09:52 -04:00
}
2023-10-04 18:57:51 -04:00
pub ( crate ) fn reset_color ( ) -> & 'static str {
2023-08-25 04:25:39 -04:00
if DiffResult ::should_use_color ( ) {
" \x1b [0m "
} else {
" "
}
}
fn should_use_color ( ) -> bool {
! std ::env ::var ( " NO_COLOR " ) . is_ok_and ( | val | ! val . is_empty ( ) )
2023-08-25 04:09:52 -04:00
}
2023-04-11 17:35:09 -04:00
}
2023-10-02 12:28:48 -04:00
impl < ' b , ' s > DiffLayer < ' b , ' s > {
2023-08-29 22:47:40 -04:00
fn has_bad_children ( & self ) -> bool {
self . children
. iter ( )
. any ( | child | child . is_immediately_bad ( ) | | child . has_bad_children ( ) )
}
fn print_indented (
& self ,
indentation : usize ,
original_document : & str ,
) -> Result < ( ) , Box < dyn std ::error ::Error > > {
let status_text = if self . has_bad_children ( ) {
format! (
" {color}BADCHILD{reset} " ,
color = DiffResult ::foreground_color ( 255 , 255 , 0 ) ,
reset = DiffResult ::reset_color ( ) ,
)
} else {
format! (
" {color}GOOD{reset} " ,
color = DiffResult ::foreground_color ( 0 , 255 , 0 ) ,
reset = DiffResult ::reset_color ( ) ,
)
} ;
println! (
" {indentation}{status_text} {name} " ,
indentation = " " . repeat ( indentation ) ,
status_text = status_text ,
name = self . name ,
) ;
for child in self . children . iter ( ) {
child . print_indented ( indentation + 1 , original_document ) ? ;
}
Ok ( ( ) )
}
}
2023-10-09 15:13:05 -04:00
pub ( crate ) fn artificial_diff_scope < ' b , ' s > (
name : & ' s str ,
2023-10-02 12:28:48 -04:00
children : Vec < DiffEntry < ' b , ' s > > ,
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-09-23 21:03:12 -04:00
Ok ( DiffLayer {
name : name . into ( ) ,
children ,
}
. into ( ) )
2023-08-29 19:22:11 -04:00
}
2023-10-09 13:00:47 -04:00
pub ( crate ) fn compare_ast_node < ' b , ' s > (
2023-10-02 12:28:48 -04:00
source : & ' s str ,
emacs : & ' b Token < ' s > ,
rust : AstNode < ' b , ' s > ,
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
let compare_result : Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > = match rust {
2023-10-02 13:05:29 -04:00
AstNode ::Document ( node ) = > _compare_document ( source , emacs , node ) ,
2023-10-02 12:53:23 -04:00
AstNode ::Heading ( node ) = > compare_heading ( source , emacs , node ) ,
AstNode ::Section ( node ) = > compare_section ( source , emacs , node ) ,
AstNode ::Paragraph ( node ) = > compare_paragraph ( source , emacs , node ) ,
AstNode ::PlainList ( node ) = > compare_plain_list ( source , emacs , node ) ,
AstNode ::PlainListItem ( node ) = > compare_plain_list_item ( source , emacs , node ) ,
2023-10-02 22:21:24 -04:00
AstNode ::CenterBlock ( node ) = > compare_center_block ( source , emacs , node ) ,
AstNode ::QuoteBlock ( node ) = > compare_quote_block ( source , emacs , node ) ,
AstNode ::SpecialBlock ( node ) = > compare_special_block ( source , emacs , node ) ,
2023-10-02 12:53:23 -04:00
AstNode ::DynamicBlock ( node ) = > compare_dynamic_block ( source , emacs , node ) ,
AstNode ::FootnoteDefinition ( node ) = > compare_footnote_definition ( source , emacs , node ) ,
AstNode ::Comment ( node ) = > compare_comment ( source , emacs , node ) ,
AstNode ::Drawer ( node ) = > compare_drawer ( source , emacs , node ) ,
AstNode ::PropertyDrawer ( node ) = > compare_property_drawer ( source , emacs , node ) ,
AstNode ::NodeProperty ( node ) = > compare_node_property ( source , emacs , node ) ,
AstNode ::Table ( node ) = > compare_table ( source , emacs , node ) ,
AstNode ::TableRow ( node ) = > compare_table_row ( source , emacs , node ) ,
AstNode ::VerseBlock ( node ) = > compare_verse_block ( source , emacs , node ) ,
AstNode ::CommentBlock ( node ) = > compare_comment_block ( source , emacs , node ) ,
AstNode ::ExampleBlock ( node ) = > compare_example_block ( source , emacs , node ) ,
AstNode ::ExportBlock ( node ) = > compare_export_block ( source , emacs , node ) ,
AstNode ::SrcBlock ( node ) = > compare_src_block ( source , emacs , node ) ,
AstNode ::Clock ( node ) = > compare_clock ( source , emacs , node ) ,
AstNode ::DiarySexp ( node ) = > compare_diary_sexp ( source , emacs , node ) ,
AstNode ::Planning ( node ) = > compare_planning ( source , emacs , node ) ,
AstNode ::FixedWidthArea ( node ) = > compare_fixed_width_area ( source , emacs , node ) ,
AstNode ::HorizontalRule ( node ) = > compare_horizontal_rule ( source , emacs , node ) ,
AstNode ::Keyword ( node ) = > compare_keyword ( source , emacs , node ) ,
AstNode ::BabelCall ( node ) = > compare_babel_call ( source , emacs , node ) ,
AstNode ::LatexEnvironment ( node ) = > compare_latex_environment ( source , emacs , node ) ,
AstNode ::Bold ( node ) = > compare_bold ( source , emacs , node ) ,
AstNode ::Italic ( node ) = > compare_italic ( source , emacs , node ) ,
AstNode ::Underline ( node ) = > compare_underline ( source , emacs , node ) ,
AstNode ::StrikeThrough ( node ) = > compare_strike_through ( source , emacs , node ) ,
AstNode ::Code ( node ) = > compare_code ( source , emacs , node ) ,
AstNode ::Verbatim ( node ) = > compare_verbatim ( source , emacs , node ) ,
AstNode ::PlainText ( node ) = > compare_plain_text ( source , emacs , node ) ,
AstNode ::RegularLink ( node ) = > compare_regular_link ( source , emacs , node ) ,
AstNode ::RadioLink ( node ) = > compare_radio_link ( source , emacs , node ) ,
AstNode ::RadioTarget ( node ) = > compare_radio_target ( source , emacs , node ) ,
AstNode ::PlainLink ( node ) = > compare_plain_link ( source , emacs , node ) ,
AstNode ::AngleLink ( node ) = > compare_angle_link ( source , emacs , node ) ,
AstNode ::OrgMacro ( node ) = > compare_org_macro ( source , emacs , node ) ,
AstNode ::Entity ( node ) = > compare_entity ( source , emacs , node ) ,
AstNode ::LatexFragment ( node ) = > compare_latex_fragment ( source , emacs , node ) ,
AstNode ::ExportSnippet ( node ) = > compare_export_snippet ( source , emacs , node ) ,
AstNode ::FootnoteReference ( node ) = > compare_footnote_reference ( source , emacs , node ) ,
AstNode ::Citation ( node ) = > compare_citation ( source , emacs , node ) ,
AstNode ::CitationReference ( node ) = > compare_citation_reference ( source , emacs , node ) ,
AstNode ::InlineBabelCall ( node ) = > compare_inline_babel_call ( source , emacs , node ) ,
AstNode ::InlineSourceBlock ( node ) = > compare_inline_source_block ( source , emacs , node ) ,
AstNode ::LineBreak ( node ) = > compare_line_break ( source , emacs , node ) ,
AstNode ::Target ( node ) = > compare_target ( source , emacs , node ) ,
AstNode ::StatisticsCookie ( node ) = > compare_statistics_cookie ( source , emacs , node ) ,
AstNode ::Subscript ( node ) = > compare_subscript ( source , emacs , node ) ,
AstNode ::Superscript ( node ) = > compare_superscript ( source , emacs , node ) ,
AstNode ::TableCell ( node ) = > compare_table_cell ( source , emacs , node ) ,
2023-10-02 12:28:48 -04:00
AstNode ::Timestamp ( node ) = > compare_timestamp ( source , emacs , node ) ,
} ;
2023-10-02 12:36:09 -04:00
let mut compare_result = match compare_result . unwrap_or_else ( | e | {
DiffResult {
status : DiffStatus ::Bad ,
2023-10-02 13:05:29 -04:00
name : rust . get_elisp_fact ( ) . get_elisp_name ( ) ,
2023-10-02 12:36:09 -04:00
message : Some ( e . to_string ( ) ) ,
children : Vec ::new ( ) ,
rust_source : rust . get_standard_properties ( ) . get_source ( ) ,
emacs_token : emacs ,
}
. into ( )
} ) {
DiffEntry ::DiffResult ( inner ) = > inner ,
DiffEntry ::DiffLayer ( _ ) = > {
unreachable! ( " Layers are only interior to DiffResults of AST nodes. " )
}
} ;
2023-10-02 12:53:23 -04:00
// PlainText is a special case because upstream Org-Mode uses relative values for the bounds in plaintext rather than absolute so the below checks do not account for that.
if let AstNode ::PlainText ( _ ) = rust {
} else {
match compare_standard_properties ( source , emacs , & rust ) {
Err ( err ) = > {
compare_result . status = DiffStatus ::Bad ;
compare_result . message = Some ( err . to_string ( ) )
}
Ok ( _ ) = > { }
2023-10-02 12:36:09 -04:00
}
}
Ok ( compare_result . into ( ) )
2023-10-02 12:28:48 -04:00
}
2023-10-02 13:05:29 -04:00
pub fn compare_document < ' b , ' s > (
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
2023-10-02 13:05:29 -04:00
rust : & ' b Document < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-02 13:05:29 -04:00
compare_ast_node ( rust . source , emacs , rust . into ( ) )
2023-04-22 17:58:16 -04:00
}
2023-10-02 13:05:29 -04:00
fn _compare_document < ' b , ' s > (
2023-10-02 13:05:51 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Document < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-11 17:35:09 -04:00
let children = emacs . as_list ( ) ? ;
2023-04-11 18:27:01 -04:00
let mut child_status = Vec ::new ( ) ;
2023-04-11 19:16:04 -04:00
let mut this_status = DiffStatus ::Good ;
2023-09-23 21:03:12 -04:00
let mut message = None ;
2023-04-11 17:35:09 -04:00
2023-09-29 21:20:23 -04:00
// Compare :path
2023-09-29 21:14:55 -04:00
// :path is a quoted string to the absolute path of the document.
let document_path = get_property_quoted_string ( emacs , " :path " ) ? ;
2023-09-29 21:20:23 -04:00
let rust_document_path = rust . path . as_ref ( ) . map ( | p | p . to_str ( ) ) . flatten ( ) ;
match (
document_path . as_ref ( ) . map ( | s | s . as_str ( ) ) ,
rust_document_path ,
) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Path mismatch (emacs != rust) {:?} != {:?} " ,
document_path , rust_document_path
) ) ;
}
( Some ( e ) , Some ( r ) ) if e ! = r = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Path mismatch (emacs != rust) {:?} != {:?} " ,
document_path , rust_document_path
) ) ;
}
( Some ( _ ) , Some ( _ ) ) = > { }
} ;
2023-09-29 20:23:02 -04:00
// Compare category
2023-09-29 21:14:55 -04:00
// :CATEGORY is specified either from "#+CATEGORY:" or it is the file name without the ".org" extension.
2023-09-29 20:23:02 -04:00
let category = get_property_quoted_string ( emacs , " :CATEGORY " ) ? ;
2023-09-29 21:14:55 -04:00
match ( category . as_ref ( ) , rust . category . as_ref ( ) ) {
2023-09-29 20:23:02 -04:00
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Category mismatch (emacs != rust) {:?} != {:?} " ,
category , rust . category
) ) ;
}
( Some ( e ) , Some ( r ) ) if e ! = r = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Category mismatch (emacs != rust) {:?} != {:?} " ,
category , rust . category
) ) ;
}
( Some ( _ ) , Some ( _ ) ) = > { }
} ;
2023-09-23 14:46:36 -04:00
// Skipping "org-data" and its properties
2023-04-11 18:27:01 -04:00
for ( i , token ) in children . iter ( ) . skip ( 2 ) . enumerate ( ) {
let section_or_headline = token . as_list ( ) ? ;
let first_cell = section_or_headline
. first ( )
. ok_or ( " Should have at least one child. " ) ?
. as_atom ( ) ? ;
if first_cell = = " section " {
if i ! = 0 {
return Err ( " Section cannot be after the first child of document. " . into ( ) ) ;
}
2023-10-02 13:05:29 -04:00
child_status . push ( compare_ast_node (
2023-04-11 18:34:11 -04:00
rust . source ,
2023-04-11 18:27:01 -04:00
token ,
rust . zeroth_section
. as_ref ( )
2023-10-02 13:05:29 -04:00
. ok_or ( " No corresponding zeroth-section " ) ?
. into ( ) ,
2023-04-11 18:27:01 -04:00
) ? ) ;
} else if first_cell = = " headline " {
let corresponding_heading = rust
. children
. iter ( )
. nth ( i - rust . zeroth_section . as_ref ( ) . map ( | _ | 1 ) . unwrap_or ( 0 ) )
. ok_or ( " Should have a corresponding heading. " ) ? ;
2023-10-02 13:05:29 -04:00
child_status . push ( compare_ast_node (
rust . source ,
token ,
corresponding_heading . into ( ) ,
) ? ) ;
2023-04-11 18:27:01 -04:00
} else {
2023-09-29 22:27:31 -04:00
return Err ( format! (
" Document should only contain sections and headlines, found: {} " ,
first_cell
)
. into ( ) ) ;
2023-04-11 18:27:01 -04:00
}
}
Ok ( DiffResult {
2023-04-11 19:16:04 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
message ,
2023-04-11 18:27:01 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-11 18:27:01 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_section < ' b , ' s > (
2023-04-11 18:34:11 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Section < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 20:54:31 -04:00
let mut this_status = DiffStatus ::Good ;
2023-04-19 15:38:36 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-09 20:54:31 -04:00
let mut message = None ;
2023-04-11 19:16:04 -04:00
2023-10-09 20:54:31 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
for diff in compare_properties! ( emacs ) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-04-12 11:46:49 -04:00
}
2023-04-11 18:27:01 -04:00
Ok ( DiffResult {
2023-04-11 19:16:04 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-11 18:27:01 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
2023-10-09 21:04:41 -04:00
emacs_token : emacs ,
}
. into ( ) )
}
2023-10-09 21:35:35 -04:00
#[ allow(dead_code) ]
2023-10-09 21:04:41 -04:00
fn new_compare_heading < ' b , ' s > (
source : & ' s str ,
emacs : & ' b Token < ' s > ,
rust : & ' b Heading < ' s > ,
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error + ' s > > {
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-10-09 21:32:29 -04:00
// TODO: This needs to support additional properties from the property drawer
2023-10-09 21:04:41 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :level " ) ,
| r | Some ( r . level ) ,
compare_property_numeric
2023-10-09 21:27:18 -04:00
) ,
(
EmacsField ::Required ( " :tags " ) ,
| r | if r . tags . is_empty ( ) {
None
} else {
Some ( r . tags . iter ( ) )
} ,
compare_property_list_of_quoted_string
) ,
(
EmacsField ::Required ( " :todo-keyword " ) ,
| r | r . todo_keyword . as_ref ( ) . map ( | ( _ , text ) | text ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :todo-type " ) ,
| r | r
. todo_keyword
. as_ref ( )
. map ( | ( todo_type , _ ) | todo_type )
. map ( | todo_type | match todo_type {
TodoKeywordType ::Todo = > " todo " ,
TodoKeywordType ::Done = > " done " ,
} ) ,
compare_property_unquoted_atom
) ,
(
EmacsField ::Required ( " :title " ) ,
| r | if r . title . is_empty ( ) {
None
} else {
Some ( r . title . iter ( ) )
} ,
compare_property_list_of_ast_nodes
) ,
(
EmacsField ::Required ( " :priority " ) ,
| r | r . priority_cookie ,
compare_property_numeric
) ,
(
EmacsField ::Required ( " :archivedp " ) ,
| r | r . is_archived ,
compare_property_boolean
) ,
(
EmacsField ::Required ( " :commentedp " ) ,
| r | r . is_comment ,
compare_property_boolean
) ,
(
EmacsField ::Required ( " :raw-value " ) ,
| r | Some ( r . get_raw_value ( ) ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :footnote-section-p " ) ,
| r | r . is_footnote_section ,
compare_property_boolean
) ,
(
2023-10-09 21:32:29 -04:00
EmacsField ::Optional ( " :scheduled " ) ,
2023-10-09 21:27:18 -04:00
| r | r . scheduled . as_ref ( ) ,
compare_property_single_ast_node
) ,
(
2023-10-09 21:32:29 -04:00
EmacsField ::Optional ( " :deadline " ) ,
2023-10-09 21:27:18 -04:00
| r | r . deadline . as_ref ( ) ,
compare_property_single_ast_node
) ,
(
2023-10-09 21:32:29 -04:00
EmacsField ::Optional ( " :closed " ) ,
2023-10-09 21:27:18 -04:00
| r | r . closed . as_ref ( ) ,
compare_property_single_ast_node
) ,
(
EmacsField ::Required ( " :pre-blank " ) ,
compare_identity ,
compare_noop
2023-10-09 21:04:41 -04:00
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
Ok ( DiffResult {
status : this_status ,
name : rust . get_elisp_name ( ) ,
message ,
children : child_status ,
rust_source : rust . get_source ( ) ,
2023-08-29 14:40:58 -04:00
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-11 18:27:01 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_heading < ' b , ' s > (
2023-04-11 18:34:11 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Heading < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-11 18:27:01 -04:00
let children = emacs . as_list ( ) ? ;
let mut child_status = Vec ::new ( ) ;
2023-04-11 19:16:04 -04:00
let mut this_status = DiffStatus ::Good ;
2023-08-25 06:46:00 -04:00
let mut message = None ;
2023-04-11 19:16:04 -04:00
2023-08-29 22:07:23 -04:00
// Compare level
2023-08-29 22:11:56 -04:00
let level = get_property ( emacs , " :level " ) ?
. ok_or ( " Level should not be nil " ) ?
. as_atom ( ) ? ;
2023-09-15 22:44:39 -04:00
if rust . level . to_string ( ) ! = level {
2023-08-29 22:11:56 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
2023-09-08 23:05:04 -04:00
" Headline level do not match (emacs != rust): {} != {} " ,
2023-09-15 22:44:39 -04:00
level , rust . level
2023-08-29 22:11:56 -04:00
) )
}
2023-08-29 22:07:23 -04:00
2023-08-27 15:56:08 -04:00
// Compare tags
let emacs_tags = get_tags_from_heading ( emacs ) ? ;
let emacs_tags : HashSet < _ > = emacs_tags . iter ( ) . map ( | val | val . as_str ( ) ) . collect ( ) ;
let rust_tags : HashSet < & str > = rust . tags . iter ( ) . map ( | val | * val ) . collect ( ) ;
let difference : Vec < & str > = emacs_tags
. symmetric_difference ( & rust_tags )
. map ( | val | * val )
. collect ( ) ;
if ! difference . is_empty ( ) {
this_status = DiffStatus ::Bad ;
message = Some ( format! ( " Mismatched tags: {} " , difference . join ( " , " ) ) ) ;
}
// Compare todo-keyword
2023-08-29 19:22:11 -04:00
let todo_keyword = get_property ( emacs , " :todo-keyword " ) ?
. map ( Token ::as_atom )
. map_or ( Ok ( None ) , | r | r . map ( Some ) ) ?
. unwrap_or ( " nil " ) ;
2023-09-06 12:39:03 -04:00
match ( todo_keyword , & rust . todo_keyword , unquote ( todo_keyword ) ) {
2023-08-27 15:56:08 -04:00
( " nil " , None , _ ) = > { }
2023-09-06 12:39:03 -04:00
( _ , Some ( ( _rust_todo_type , rust_todo ) ) , Ok ( emacs_todo ) ) if emacs_todo = = * rust_todo = > { }
2023-08-27 15:56:08 -04:00
( emacs_todo , rust_todo , _ ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" (emacs != rust) {:?} != {:?} " ,
emacs_todo , rust_todo
) ) ;
}
} ;
2023-09-06 12:39:03 -04:00
// Compare todo-type
let todo_type = get_property ( emacs , " :todo-type " ) ?
. map ( Token ::as_atom )
. map_or ( Ok ( None ) , | r | r . map ( Some ) ) ?
. unwrap_or ( " nil " ) ;
// todo-type is an unquoted string either todo, done, or nil
match ( todo_type , & rust . todo_keyword ) {
( " nil " , None ) = > { }
( " todo " , Some ( ( TodoKeywordType ::Todo , _ ) ) ) = > { }
( " done " , Some ( ( TodoKeywordType ::Done , _ ) ) ) = > { }
( emacs_todo , rust_todo ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" (emacs != rust) {:?} != {:?} " ,
emacs_todo , rust_todo
) ) ;
}
} ;
2023-08-27 15:56:08 -04:00
// Compare title
2023-09-14 01:41:09 -04:00
let title = get_property ( emacs , " :title " ) ? ;
match ( title , rust . title . len ( ) ) {
( None , 0 ) = > { }
( None , _ ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Titles do not match (emacs != rust): {:?} != {:?} " ,
title , rust . title
) )
}
( Some ( title ) , _ ) = > {
let title_status = title
. as_list ( ) ?
. iter ( )
. zip ( rust . title . iter ( ) )
2023-10-02 13:05:29 -04:00
. map ( | ( emacs_child , rust_child ) | {
compare_ast_node ( source , emacs_child , rust_child . into ( ) )
} )
2023-09-14 01:41:09 -04:00
. collect ::< Result < Vec < _ > , _ > > ( ) ? ;
2023-09-23 21:03:12 -04:00
child_status . push ( artificial_diff_scope ( " title " , title_status ) ? ) ;
2023-09-14 01:41:09 -04:00
}
} ;
2023-04-22 22:56:36 -04:00
2023-09-08 15:57:24 -04:00
// Compare priority
let priority = get_property ( emacs , " :priority " ) ? ;
match ( priority , rust . priority_cookie ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Priority cookie mismatch (emacs != rust) {:?} != {:?} " ,
priority , rust . priority_cookie
) ) ;
}
( Some ( emacs_priority_cookie ) , Some ( rust_priority_cookie ) ) = > {
let emacs_priority_cookie =
emacs_priority_cookie . as_atom ( ) ? . parse ::< PriorityCookie > ( ) ? ;
if emacs_priority_cookie ! = rust_priority_cookie {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Priority cookie mismatch (emacs != rust) {:?} != {:?} " ,
emacs_priority_cookie , rust_priority_cookie
) ) ;
}
}
}
// Compare archived
let archived = get_property ( emacs , " :archivedp " ) ? ;
match ( archived , rust . is_archived ) {
( None , true ) | ( Some ( _ ) , false ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" archived mismatch (emacs != rust) {:?} != {:?} " ,
archived , rust . is_archived
) ) ;
}
( None , false ) | ( Some ( _ ) , true ) = > { }
}
// Compare commented
let commented = get_property ( emacs , " :commentedp " ) ? ;
match ( commented , rust . is_comment ) {
( None , true ) | ( Some ( _ ) , false ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" commented mismatch (emacs != rust) {:?} != {:?} " ,
commented , rust . is_comment
) ) ;
}
( None , false ) | ( Some ( _ ) , true ) = > { }
}
2023-09-30 19:21:24 -04:00
// Compare raw-value
let raw_value = get_property_quoted_string ( emacs , " :raw-value " ) ?
. ok_or ( " Headlines should have :raw-value. " ) ? ;
let rust_raw_value = rust . get_raw_value ( ) ;
if raw_value ! = rust_raw_value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" raw-value mismatch (emacs != rust) {:?} != {:?} " ,
raw_value , rust_raw_value
) ) ;
}
2023-10-02 10:48:34 -04:00
// Compare footnote-section-p
let footnote_section = get_property_boolean ( emacs , " :footnote-section-p " ) ? ;
if footnote_section ! = rust . is_footnote_section {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" footnote section mismatch (emacs != rust) {:?} != {:?} " ,
footnote_section , rust . is_footnote_section
) ) ;
}
2023-10-02 20:37:46 -04:00
// Compare scheduled
let scheduled = get_property ( emacs , " :scheduled " ) ? ;
match ( scheduled , & rust . scheduled ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Scheduled mismatch (emacs != rust) {:?} != {:?} " ,
scheduled , rust . scheduled
) ) ;
}
( Some ( emacs_child ) , Some ( rust_child ) ) = > {
let result = compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ;
child_status . push ( artificial_diff_scope ( " scheduled " , vec! [ result ] ) ? ) ;
}
}
// Compare deadline
let deadline = get_property ( emacs , " :deadline " ) ? ;
match ( deadline , & rust . deadline ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Deadline mismatch (emacs != rust) {:?} != {:?} " ,
deadline , rust . deadline
) ) ;
}
( Some ( emacs_child ) , Some ( rust_child ) ) = > {
let result = compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ;
child_status . push ( artificial_diff_scope ( " deadline " , vec! [ result ] ) ? ) ;
}
}
// Compare closed
let closed = get_property ( emacs , " :closed " ) ? ;
match ( closed , & rust . closed ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Closed mismatch (emacs != rust) {:?} != {:?} " ,
closed , rust . closed
) ) ;
}
( Some ( emacs_child ) , Some ( rust_child ) ) = > {
let result = compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ;
child_status . push ( artificial_diff_scope ( " closed " , vec! [ result ] ) ? ) ;
}
}
// TODO: Compare :pre-blank
2023-08-25 06:13:29 -04:00
2023-08-27 15:56:08 -04:00
// Compare section
2023-08-29 22:57:08 -04:00
let section_status = children
. iter ( )
. skip ( 2 )
. zip ( rust . children . iter ( ) )
. map ( | ( emacs_child , rust_child ) | match rust_child {
2023-04-12 11:35:02 -04:00
DocumentElement ::Heading ( rust_heading ) = > {
2023-10-02 13:05:29 -04:00
compare_ast_node ( source , emacs_child , rust_heading . into ( ) )
2023-04-12 13:16:25 -04:00
}
2023-04-12 11:35:02 -04:00
DocumentElement ::Section ( rust_section ) = > {
2023-10-02 13:05:29 -04:00
compare_ast_node ( source , emacs_child , rust_section . into ( ) )
2023-04-12 13:16:25 -04:00
}
2023-08-29 22:57:08 -04:00
} )
. collect ::< Result < Vec < _ > , _ > > ( ) ? ;
2023-09-23 21:03:12 -04:00
child_status . push ( artificial_diff_scope ( " section " , section_status ) ? ) ;
2023-04-12 11:35:02 -04:00
2023-04-11 18:27:01 -04:00
Ok ( DiffResult {
2023-04-11 19:16:04 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-25 06:46:00 -04:00
message ,
2023-04-11 18:27:01 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-11 17:35:09 -04:00
}
2023-04-12 11:46:49 -04:00
2023-10-02 12:53:23 -04:00
fn get_tags_from_heading < ' b , ' s > (
emacs : & ' b Token < ' s > ,
2023-08-25 06:46:00 -04:00
) -> Result < HashSet < String > , Box < dyn std ::error ::Error > > {
2023-08-29 19:22:11 -04:00
let tags = match get_property ( emacs , " :tags " ) ? {
Some ( prop ) = > prop ,
None = > return Ok ( HashSet ::new ( ) ) ,
} ;
2023-08-25 06:46:00 -04:00
match tags . as_atom ( ) {
Ok ( val ) = > panic! ( " Unexpected value for tags: {:?} " , val ) ,
Err ( _ ) = > { }
} ;
let tags = {
let tags = tags . as_list ( ) ? ;
2023-08-27 15:56:08 -04:00
let strings = tags
. iter ( )
. map ( Token ::as_atom )
. collect ::< Result < Vec < & str > , _ > > ( ) ? ;
strings
. into_iter ( )
. map ( unquote )
. collect ::< Result < HashSet < String > , _ > > ( ) ?
2023-08-25 06:46:00 -04:00
} ;
Ok ( tags )
}
2023-10-02 12:28:48 -04:00
fn compare_paragraph < ' b , ' s > (
2023-04-12 11:46:49 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Paragraph < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-04 19:56:39 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 21:35:35 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-04 19:56:39 -04:00
let mut message = None ;
2023-10-09 21:35:35 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-04-12 11:46:49 -04:00
2023-10-09 21:35:35 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Optional ( " :name " ) ,
| r | r . name ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :caption " ) ,
compare_identity ,
compare_noop
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-04-22 17:58:16 -04:00
}
2023-04-12 11:46:49 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-12 11:46:49 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-12 11:46:49 -04:00
}
2023-04-12 13:16:25 -04:00
2023-10-02 12:28:48 -04:00
fn compare_plain_list < ' b , ' s > (
2023-04-12 13:16:25 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b PlainList < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-09-29 13:03:01 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 21:42:07 -04:00
let mut child_status = Vec ::new ( ) ;
2023-09-29 13:03:01 -04:00
let mut message = None ;
2023-10-09 21:42:07 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-04 20:01:09 -04:00
2023-10-09 21:42:07 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Optional ( " :name " ) ,
| r | r . name ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :caption " ) ,
compare_identity ,
compare_noop
) ,
(
EmacsField ::Required ( " :type " ) ,
| r | Some ( match r . list_type {
PlainListType ::Unordered = > " unordered " ,
PlainListType ::Ordered = > " ordered " ,
PlainListType ::Descriptive = > " descriptive " ,
} ) ,
compare_property_unquoted_atom
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
2023-09-29 13:03:01 -04:00
}
}
2023-09-21 20:58:03 -04:00
2023-04-12 13:16:25 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-12 13:16:25 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-12 13:16:25 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_plain_list_item < ' b , ' s > (
2023-04-12 14:07:33 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b PlainListItem < ' s > ,
2023-10-09 21:54:29 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error + ' s > > {
2023-04-12 14:07:33 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 21:54:29 -04:00
let mut child_status = Vec ::new ( ) ;
2023-08-29 19:22:11 -04:00
let mut message = None ;
2023-04-12 14:07:33 -04:00
2023-10-09 21:54:29 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-09-29 18:45:38 -04:00
2023-10-09 21:54:29 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :tag " ) ,
| r | if r . tag . is_empty ( ) {
None
} else {
Some ( r . tag . iter ( ) )
} ,
compare_property_list_of_ast_nodes
) ,
(
EmacsField ::Required ( " :bullet " ) ,
| r | Some ( r . bullet ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :counter " ) ,
| r | r . counter ,
compare_property_numeric
) ,
(
EmacsField ::Required ( " :checkbox " ) ,
| r | r
. checkbox
. as_ref ( )
. map ( | ( checkbox_type , _ ) | checkbox_type )
. map ( | checkbox_type | match checkbox_type {
CheckboxType ::On = > " on " ,
CheckboxType ::Trans = > " trans " ,
CheckboxType ::Off = > " off " ,
} ) ,
compare_property_unquoted_atom
) ,
(
EmacsField ::Required ( " :pre-blank " ) ,
| r | Some ( r . pre_blank ) ,
compare_property_numeric
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
2023-09-15 15:30:13 -04:00
}
2023-09-29 19:30:02 -04:00
}
2023-09-29 18:45:38 -04:00
2023-04-12 14:07:33 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 19:22:11 -04:00
message ,
2023-04-12 14:07:33 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-12 14:07:33 -04:00
}
2023-10-02 22:21:24 -04:00
fn compare_center_block < ' b , ' s > (
2023-04-12 13:45:22 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
2023-10-02 22:21:24 -04:00
rust : & ' b CenterBlock < ' s > ,
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
let children = emacs . as_list ( ) ? ;
let mut child_status = Vec ::new ( ) ;
2023-10-04 20:01:09 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-10-02 22:21:24 -04:00
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 ,
name : rust . get_elisp_name ( ) ,
message ,
children : child_status ,
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
}
. into ( ) )
}
fn compare_quote_block < ' b , ' s > (
source : & ' s str ,
emacs : & ' b Token < ' s > ,
rust : & ' b QuoteBlock < ' s > ,
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-04 20:01:09 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 21:57:11 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-04 20:01:09 -04:00
let mut message = None ;
2023-10-09 21:57:11 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-02 22:21:24 -04:00
2023-10-09 21:57:11 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Optional ( " :name " ) ,
| r | r . name ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :caption " ) ,
compare_identity ,
compare_noop
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-02 22:21:24 -04:00
}
Ok ( DiffResult {
status : this_status ,
name : rust . get_elisp_name ( ) ,
message ,
children : child_status ,
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
}
. into ( ) )
}
fn compare_special_block < ' b , ' s > (
source : & ' s str ,
emacs : & ' b Token < ' s > ,
rust : & ' b SpecialBlock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-02 22:30:42 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 22:01:26 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-02 22:30:42 -04:00
let mut message = None ;
2023-09-23 14:46:36 -04:00
2023-10-09 22:01:26 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-02 22:30:42 -04:00
2023-10-09 22:01:26 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Optional ( " :name " ) ,
| r | r . name ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :caption " ) ,
compare_identity ,
compare_noop
) ,
(
EmacsField ::Required ( " :type " ) ,
| r | Some ( r . block_type ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :parameters " ) ,
| r | r . parameters ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :results " ) ,
compare_identity ,
compare_noop
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
2023-10-02 22:30:42 -04:00
}
}
2023-10-02 22:21:24 -04:00
2023-04-12 13:45:22 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-12 13:45:22 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-19 13:59:17 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_dynamic_block < ' b , ' s > (
2023-04-19 13:59:17 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b DynamicBlock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-02 22:41:56 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 22:28:32 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-02 22:41:56 -04:00
let mut message = None ;
2023-10-09 22:28:32 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-02 22:41:56 -04:00
2023-10-09 22:28:32 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Optional ( " :name " ) ,
| r | r . name ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :caption " ) ,
compare_identity ,
compare_noop
) ,
(
EmacsField ::Required ( " :block-name " ) ,
| r | Some ( r . block_name ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :arguments " ) ,
| r | r . parameters ,
compare_property_quoted_string
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
2023-10-02 22:41:56 -04:00
}
}
2023-09-20 02:37:26 -04:00
2023-04-19 13:59:17 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-19 13:59:17 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-12 13:45:22 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_footnote_definition < ' b , ' s > (
2023-04-12 13:45:22 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b FootnoteDefinition < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-02 22:48:54 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 22:32:25 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-02 22:48:54 -04:00
let mut message = None ;
2023-10-04 20:01:09 -04:00
2023-10-09 22:32:25 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-09-23 14:46:36 -04:00
2023-10-09 22:32:25 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Optional ( " :name " ) ,
| r | r . name ,
compare_property_quoted_string
) ,
(
EmacsField ::Optional ( " :caption " ) ,
compare_identity ,
compare_noop
) ,
(
EmacsField ::Required ( " :label " ) ,
| r | Some ( r . label ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :pre-blank " ) ,
compare_identity ,
compare_noop
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-04-12 13:45:22 -04:00
}
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-12 13:45:22 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-12 13:45:22 -04:00
}
2023-04-15 16:53:58 -04:00
2023-10-02 12:28:48 -04:00
fn compare_comment < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Comment < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 18:42:31 -04:00
let child_status = Vec ::new ( ) ;
2023-10-02 23:28:32 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
// Compare value
let value =
get_property_quoted_string ( emacs , " :value " ) ? . ok_or ( " Comments should have a value. " ) ? ;
let rust_value = rust . get_value ( ) ;
if value ! = rust_value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
value , rust_value
) ) ;
}
2023-09-23 14:46:36 -04:00
2023-04-15 16:53:58 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-15 16:53:58 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-15 16:53:58 -04:00
}
2023-04-15 18:00:34 -04:00
2023-10-02 12:28:48 -04:00
fn compare_drawer < ' b , ' s > (
2023-04-15 18:00:34 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Drawer < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-15 18:00:34 -04:00
let children = emacs . as_list ( ) ? ;
let mut child_status = Vec ::new ( ) ;
2023-10-02 23:34:06 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// Compare name
let name = get_property_quoted_string ( emacs , " :name " ) ? ;
if name . as_ref ( ) . map ( String ::as_str ) ! = rust . name {
2023-10-02 23:34:06 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Name mismatch (emacs != rust) {:?} != {:?} " ,
name , rust . name
) ) ;
}
2023-09-23 14:46:36 -04:00
2023-10-04 20:01:09 -04:00
// Compare drawer-name
let drawer_name =
get_property_quoted_string ( emacs , " :drawer-name " ) ? . ok_or ( " Drawers should have a name. " ) ? ;
if drawer_name ! = rust . drawer_name {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Drawer name mismatch (emacs != rust) {:?} != {:?} " ,
drawer_name , rust . drawer_name
) ) ;
}
2023-04-15 18:00:34 -04:00
for ( emacs_child , rust_child ) in children . iter ( ) . skip ( 2 ) . zip ( rust . children . iter ( ) ) {
2023-10-02 13:05:29 -04:00
child_status . push ( compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ) ;
2023-04-15 18:00:34 -04:00
}
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-15 18:00:34 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-15 18:00:34 -04:00
}
2023-04-19 16:51:00 -04:00
2023-10-02 12:28:48 -04:00
fn compare_property_drawer < ' b , ' s > (
2023-04-19 16:51:00 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b PropertyDrawer < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-19 16:51:00 -04:00
let children = emacs . as_list ( ) ? ;
2023-09-06 18:49:59 -04:00
let mut child_status = Vec ::new ( ) ;
2023-09-23 21:03:12 -04:00
let this_status = DiffStatus ::Good ;
let message = None ;
2023-04-19 16:51:00 -04:00
2023-09-06 18:49:59 -04:00
for ( emacs_child , rust_child ) in children . iter ( ) . skip ( 2 ) . zip ( rust . children . iter ( ) ) {
2023-10-02 13:05:29 -04:00
child_status . push ( compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ) ;
2023-04-19 16:51:00 -04:00
}
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-19 16:51:00 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-19 16:51:00 -04:00
}
2023-04-19 20:59:58 -04:00
2023-10-02 12:28:48 -04:00
fn compare_node_property < ' b , ' s > (
2023-10-02 13:05:51 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b NodeProperty < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-09-06 18:49:59 -04:00
let child_status = Vec ::new ( ) ;
2023-10-02 23:45:31 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
// Compare key
let key =
get_property_quoted_string ( emacs , " :key " ) ? . ok_or ( " Node properties should have a key. " ) ? ;
2023-10-04 20:01:09 -04:00
if key ! = rust . property_name {
2023-10-02 23:45:31 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Key mismatch (emacs != rust) {:?} != {:?} " ,
2023-10-04 20:01:09 -04:00
key , rust . property_name
2023-10-02 23:45:31 -04:00
) ) ;
}
2023-09-06 18:49:59 -04:00
2023-10-02 23:45:31 -04:00
// Compare value
let value = get_property_quoted_string ( emacs , " :value " ) ? ;
match ( value . as_ref ( ) , rust . value ) {
( None , None ) = > { }
( Some ( emacs_value ) , Some ( rust_value ) ) if emacs_value = = rust_value = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
value , rust . value
) ) ;
}
}
2023-09-06 18:49:59 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-09-06 18:49:59 -04:00
message ,
children : child_status ,
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
}
. into ( ) )
}
2023-10-02 12:28:48 -04:00
fn compare_table < ' b , ' s > (
2023-04-19 20:59:58 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Table < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-19 20:59:58 -04:00
let children = emacs . as_list ( ) ? ;
let mut child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
2023-08-29 21:05:51 -04:00
let mut message = None ;
2023-04-19 20:59:58 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-09-08 23:05:04 -04:00
// Compare formulas
2023-09-08 22:42:24 -04:00
//
2023-09-08 23:05:04 -04:00
// :tblfm is either nil or a list () filled with quoted strings containing the value for any tblfm keywords at the end of the table.
let emacs_formulas = get_property ( emacs , " :tblfm " ) ? ;
if let Some ( emacs_formulas ) = emacs_formulas {
let emacs_formulas = emacs_formulas . as_list ( ) ? ;
if emacs_formulas . len ( ) ! = rust . formulas . len ( ) {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Formulas do not match (emacs != rust): {:?} != {:?} " ,
emacs_formulas , rust . formulas
) )
} else {
let atoms = emacs_formulas
. into_iter ( )
. map ( Token ::as_atom )
. collect ::< Result < Vec < _ > , _ > > ( ) ? ;
let unquoted = atoms
. into_iter ( )
. map ( unquote )
. collect ::< Result < BTreeSet < _ > , _ > > ( ) ? ;
for kw in & rust . formulas {
if ! unquoted . contains ( kw . value ) {
this_status = DiffStatus ::Bad ;
message = Some ( format! ( " Could not find formula in emacs: {} " , kw . value ) )
}
}
}
} else {
if ! rust . formulas . is_empty ( ) {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Formulas do not match (emacs != rust): {:?} != {:?} " ,
emacs_formulas , rust . formulas
) )
}
}
2023-09-08 22:42:24 -04:00
2023-10-02 23:57:17 -04:00
// Compare type
let table_type = get_property_unquoted_atom ( emacs , " :type " ) ? . expect ( " Table should have a type " ) ;
if table_type ! = " org " {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Table type mismatch (emacs != rust) {:?} != {:?} " ,
table_type , " org "
) ) ;
}
// Compare value
let value = get_property ( emacs , " :value " ) ? ;
if value . is_some ( ) {
2023-10-03 00:13:15 -04:00
// I don't know what :value is for, but it seems to always be nil. This is here to alert me to value being non-nil so I can investigate.
2023-10-02 23:57:17 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! ( " Non-nil value {:?} " , value ) )
}
2023-09-23 14:46:36 -04:00
2023-04-21 15:45:35 -04:00
for ( emacs_child , rust_child ) in children . iter ( ) . skip ( 2 ) . zip ( rust . children . iter ( ) ) {
2023-10-02 13:05:29 -04:00
child_status . push ( compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ) ;
2023-04-21 15:45:35 -04:00
}
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 15:45:35 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 15:45:35 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_table_row < ' b , ' s > (
2023-04-21 15:45:35 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b TableRow < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 15:45:35 -04:00
let children = emacs . as_list ( ) ? ;
let mut child_status = Vec ::new ( ) ;
2023-10-03 00:03:58 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 15:45:35 -04:00
2023-10-03 00:03:58 -04:00
// Compare type
let row_type = get_property_unquoted_atom ( emacs , " :type " ) ? ;
let rust_row_type = rust . get_type ( ) ;
match ( row_type , & rust_row_type ) {
( Some ( " standard " ) , TableRowType ::Standard ) = > { }
( Some ( " rule " ) , TableRowType ::Rule ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Type mismatch (emacs != rust) {:?} != {:?} " ,
row_type , rust_row_type
) ) ;
}
}
2023-09-08 22:42:24 -04:00
2023-04-21 15:45:35 -04:00
for ( emacs_child , rust_child ) in children . iter ( ) . skip ( 2 ) . zip ( rust . children . iter ( ) ) {
2023-10-02 13:05:29 -04:00
child_status . push ( compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ) ;
2023-04-21 15:45:35 -04:00
}
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 15:45:35 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 15:45:35 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_table_cell < ' b , ' s > (
2023-10-02 13:05:51 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b TableCell < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 15:45:35 -04:00
let children = emacs . as_list ( ) ? ;
2023-04-21 18:42:31 -04:00
let child_status = Vec ::new ( ) ;
2023-10-02 13:05:51 -04:00
let this_status = DiffStatus ::Good ;
let message = None ;
2023-04-21 15:45:35 -04:00
2023-04-21 18:42:31 -04:00
for ( _emacs_child , _rust_child ) in children . iter ( ) . skip ( 2 ) . zip ( rust . children . iter ( ) ) { }
2023-04-21 15:45:35 -04:00
2023-04-19 20:59:58 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-19 20:59:58 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-19 20:59:58 -04:00
}
2023-04-21 16:31:25 -04:00
2023-10-02 12:28:48 -04:00
fn compare_verse_block < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b VerseBlock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 18:05:40 -04:00
let children = emacs . as_list ( ) ? ;
2023-04-21 18:42:31 -04:00
let child_status = Vec ::new ( ) ;
2023-10-04 19:42:14 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 18:05:40 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 19:42:14 -04:00
// 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
) ) ;
}
2023-10-04 19:37:14 -04:00
2023-04-21 18:42:31 -04:00
for ( _emacs_child , _rust_child ) in children . iter ( ) . skip ( 2 ) . zip ( rust . children . iter ( ) ) { }
2023-04-21 18:05:40 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 18:05:40 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 17:40:49 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_comment_block < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b CommentBlock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-04 09:35:19 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 18:05:40 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 19:42:14 -04:00
// 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
) ) ;
}
2023-10-04 19:37:14 -04:00
2023-10-04 09:35:19 -04:00
// Compare value
let contents = get_property_quoted_string ( emacs , " :value " ) ? . unwrap_or ( String ::new ( ) ) ;
if contents ! = rust . contents {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
contents , rust . contents
) ) ;
}
2023-09-23 14:46:36 -04:00
2023-04-21 18:05:40 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 18:05:40 -04:00
children : Vec ::new ( ) ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 17:40:49 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_example_block < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b ExampleBlock < ' s > ,
2023-10-04 15:20:57 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error + ' s > > {
2023-10-04 09:51:28 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 18:05:40 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 19:42:14 -04:00
// 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
) ) ;
}
2023-10-04 19:34:10 -04:00
2023-10-04 09:51:28 -04:00
// Compare value
let contents = get_property_quoted_string ( emacs , " :value " ) ? . unwrap_or ( String ::new ( ) ) ;
2023-10-04 13:23:57 -04:00
if contents ! = rust . contents {
2023-10-04 09:51:28 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
2023-10-04 13:23:57 -04:00
contents , rust . contents
2023-10-04 09:51:28 -04:00
) ) ;
}
2023-09-23 14:46:36 -04:00
2023-10-04 10:03:51 -04:00
// Compare switches
let switches = get_property_quoted_string ( emacs , " :switches " ) ? ;
2023-10-04 14:49:08 -04:00
match ( switches . as_ref ( ) . map ( String ::as_str ) , rust . switches ) {
( None , None ) = > { }
( Some ( " " ) , None ) = > { }
( None , Some ( " " ) ) = > {
unreachable! ( " The organic parser would return a None instead of an empty string. " ) ;
}
( Some ( e ) , Some ( r ) ) if e = = r = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Switches mismatch (emacs != rust) {:?} != {:?} " ,
switches , rust . switches
) ) ;
}
2023-10-04 10:03:51 -04:00
}
2023-10-04 10:31:01 -04:00
// Compare number-lines
let number_lines = get_property ( emacs , " :number-lines " ) ? ;
match ( number_lines , & rust . number_lines ) {
( 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 = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Number lines mismatch (emacs != rust) {:?} != {:?} " ,
number_lines , rust . number_lines
) ) ;
}
}
}
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Number lines mismatch (emacs != rust) {:?} != {:?} " ,
number_lines , rust . number_lines
) ) ;
}
} ;
2023-10-04 12:36:38 -04:00
// Compare preserve-indent
2023-10-04 19:23:47 -04:00
let preserve_indent : Option < CharOffsetInLine > =
get_property_numeric ( emacs , " :preserve-indent " ) ? ;
if preserve_indent ! = rust . preserve_indent {
2023-10-04 12:36:38 -04:00
this_status = DiffStatus ::Bad ;
2023-10-04 19:23:47 -04:00
message = Some ( format! (
" Prserve indent mismatch (emacs != rust) {:?} != {:?} " ,
preserve_indent , rust . preserve_indent
) ) ;
2023-10-04 12:36:38 -04:00
}
// Compare retain-labels
2023-10-04 16:21:37 -04:00
// retain-labels is t by default, nil if -r is set, or a number if -k and -r is set.
2023-10-04 15:43:09 -04:00
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
) ) ;
}
}
2023-10-04 12:36:38 -04:00
}
// 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
) ) ;
}
}
2023-04-21 18:05:40 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 18:05:40 -04:00
children : Vec ::new ( ) ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 17:40:49 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_export_block < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b ExportBlock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-04 19:42:14 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 18:05:40 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-05 02:06:26 -04:00
2023-10-05 02:15:32 -04:00
// Compare type
let export_type = get_property_quoted_string ( emacs , " :type " ) ? ;
let rust_export_type = rust . get_export_type ( ) ;
if export_type ! = rust_export_type {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Export type mismatch (emacs != rust) {:?} != {:?} " ,
export_type , rust . export_type
) ) ;
}
2023-10-05 02:06:26 -04:00
// Compare value
let contents = get_property_quoted_string ( emacs , " :value " ) ? . unwrap_or ( String ::new ( ) ) ;
if contents ! = rust . contents {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
contents , rust . contents
) ) ;
}
2023-10-04 19:42:14 -04:00
// 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
) ) ;
}
2023-09-23 14:46:36 -04:00
2023-04-21 18:05:40 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 18:05:40 -04:00
children : Vec ::new ( ) ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 17:40:49 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_src_block < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b SrcBlock < ' s > ,
2023-10-04 16:58:45 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error + ' s > > {
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 19:42:14 -04:00
// 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
) ) ;
}
2023-10-04 19:37:14 -04:00
2023-10-04 16:58:45 -04:00
// Compare language
let language = get_property_quoted_string ( emacs , " :language " ) ? ;
if language . as_ref ( ) . map ( String ::as_str ) ! = rust . language {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Language mismatch (emacs != rust) {:?} != {:?} " ,
language , rust . language
) ) ;
}
// Compare value
let contents = get_property_quoted_string ( emacs , " :value " ) ? . unwrap_or ( String ::new ( ) ) ;
if contents ! = rust . contents {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
contents , rust . contents
) ) ;
}
// Compare switches
let switches = get_property_quoted_string ( emacs , " :switches " ) ? ;
match ( switches . as_ref ( ) . map ( String ::as_str ) , rust . switches ) {
( None , None ) = > { }
( Some ( " " ) , None ) = > { }
( None , Some ( " " ) ) = > {
unreachable! ( " The organic parser would return a None instead of an empty string. " ) ;
}
( Some ( e ) , Some ( r ) ) if e = = r = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Switches mismatch (emacs != rust) {:?} != {:?} " ,
switches , rust . switches
) ) ;
}
}
2023-10-04 19:23:47 -04:00
// Compare parameters
2023-10-04 18:02:50 -04:00
let parameters = get_property_quoted_string ( emacs , " :parameters " ) ? ;
match ( parameters . as_ref ( ) . map ( String ::as_str ) , rust . parameters ) {
( None , None ) = > { }
( Some ( " " ) , None ) = > { }
( None , Some ( " " ) ) = > {
unreachable! ( " The organic parser would return a None instead of an empty string. " ) ;
}
( Some ( e ) , Some ( r ) ) if e = = r = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Parameters mismatch (emacs != rust) {:?} != {:?} " ,
parameters , rust . parameters
) ) ;
}
}
2023-10-04 16:58:45 -04:00
// Compare number-lines
let number_lines = get_property ( emacs , " :number-lines " ) ? ;
match ( number_lines , & rust . number_lines ) {
( 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 = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Number lines mismatch (emacs != rust) {:?} != {:?} " ,
number_lines , rust . number_lines
) ) ;
}
}
}
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Number lines mismatch (emacs != rust) {:?} != {:?} " ,
number_lines , rust . number_lines
) ) ;
}
} ;
// Compare preserve-indent
2023-10-04 19:23:47 -04:00
let preserve_indent : Option < CharOffsetInLine > =
get_property_numeric ( emacs , " :preserve-indent " ) ? ;
if preserve_indent ! = rust . preserve_indent {
2023-10-04 16:58:45 -04:00
this_status = DiffStatus ::Bad ;
2023-10-04 19:23:47 -04:00
message = Some ( format! (
" Prserve indent mismatch (emacs != rust) {:?} != {:?} " ,
preserve_indent , rust . preserve_indent
) ) ;
2023-10-04 16:58:45 -04:00
}
// 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
) ) ;
}
2023-04-21 18:05:40 -04:00
2023-10-04 16:58:45 -04:00
// 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
) ) ;
}
}
2023-09-06 18:11:57 -04:00
2023-04-21 18:05:40 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 18:05:40 -04:00
children : Vec ::new ( ) ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 16:31:25 -04:00
}
2023-04-21 19:02:16 -04:00
2023-10-02 12:28:48 -04:00
fn compare_clock < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Clock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-05 03:19:17 -04:00
let mut child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
// Compare value
let value = get_property ( emacs , " :value " ) ? ;
match value {
Some ( e ) = > {
let result = compare_ast_node ( _source , e , ( & rust . timestamp ) . into ( ) ) ? ;
child_status . push ( artificial_diff_scope ( " value " , vec! [ result ] ) ? ) ;
}
None = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
value , rust . timestamp
) ) ;
}
}
2023-04-21 19:02:16 -04:00
2023-10-05 03:19:17 -04:00
// Compare duration
let duration = get_property_quoted_string ( emacs , " :duration " ) ? ;
if duration . as_ref ( ) . map ( String ::as_str ) ! = rust . duration {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Duration mismatch (emacs != rust) {:?} != {:?} " ,
duration , rust . duration
) ) ;
}
// Compare status
let status = get_property_unquoted_atom ( emacs , " :status " ) ? ;
match ( status , & rust . status ) {
( Some ( " running " ) , ClockStatus ::Running ) = > { }
( Some ( " closed " ) , ClockStatus ::Closed ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Status mismatch (emacs != rust) {:?} != {:?} " ,
status , rust . status
) ) ;
}
}
2023-09-23 14:46:36 -04:00
2023-04-21 19:02:16 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-05 03:19:17 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 19:02:16 -04:00
}
2023-04-21 20:22:31 -04:00
2023-10-02 12:28:48 -04:00
fn compare_diary_sexp < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b DiarySexp < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-04 20:01:09 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 20:22:31 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-10-05 03:46:14 -04:00
// Compare value
let value = get_property_quoted_string ( emacs , " :value " ) ? ;
if value . as_ref ( ) . map ( String ::as_str ) ! = Some ( rust . value ) {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
value , rust . value
) ) ;
}
2023-04-21 20:22:31 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 20:22:31 -04:00
children : Vec ::new ( ) ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 20:22:31 -04:00
}
2023-04-21 21:33:23 -04:00
2023-10-02 12:28:48 -04:00
fn compare_planning < ' b , ' s > (
2023-10-02 20:37:46 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Planning < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-02 20:25:08 -04:00
let mut child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 21:33:23 -04:00
2023-10-02 20:25:08 -04:00
// Compare scheduled
let scheduled = get_property ( emacs , " :scheduled " ) ? ;
match ( scheduled , & rust . scheduled ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Scheduled mismatch (emacs != rust) {:?} != {:?} " ,
scheduled , rust . scheduled
) ) ;
}
( Some ( emacs_child ) , Some ( rust_child ) ) = > {
2023-10-02 20:37:46 -04:00
let result = compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ;
2023-10-02 20:25:08 -04:00
child_status . push ( artificial_diff_scope ( " scheduled " , vec! [ result ] ) ? ) ;
}
}
// Compare deadline
let deadline = get_property ( emacs , " :deadline " ) ? ;
match ( deadline , & rust . deadline ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Deadline mismatch (emacs != rust) {:?} != {:?} " ,
deadline , rust . deadline
) ) ;
}
( Some ( emacs_child ) , Some ( rust_child ) ) = > {
2023-10-02 20:37:46 -04:00
let result = compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ;
2023-10-02 20:25:08 -04:00
child_status . push ( artificial_diff_scope ( " deadline " , vec! [ result ] ) ? ) ;
}
}
// Compare closed
let closed = get_property ( emacs , " :closed " ) ? ;
match ( closed , & rust . closed ) {
( None , None ) = > { }
( None , Some ( _ ) ) | ( Some ( _ ) , None ) = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Closed mismatch (emacs != rust) {:?} != {:?} " ,
closed , rust . closed
) ) ;
}
( Some ( emacs_child ) , Some ( rust_child ) ) = > {
2023-10-02 20:37:46 -04:00
let result = compare_ast_node ( source , emacs_child , rust_child . into ( ) ) ? ;
2023-10-02 20:25:08 -04:00
child_status . push ( artificial_diff_scope ( " closed " , vec! [ result ] ) ? ) ;
}
}
2023-09-23 14:46:36 -04:00
2023-04-21 21:33:23 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-02 20:25:08 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 21:33:23 -04:00
}
2023-04-21 22:04:22 -04:00
2023-10-02 12:28:48 -04:00
fn compare_fixed_width_area < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b FixedWidthArea < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 22:04:22 -04:00
let child_status = Vec ::new ( ) ;
2023-10-04 20:01:09 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-21 22:04:22 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-10-05 03:58:42 -04:00
// Compare value
let value = get_property_quoted_string ( emacs , " :value " ) ?
. ok_or ( " Fixed width area should have a value. " ) ? ;
let rust_value = rust . get_value ( ) ;
if value ! = rust_value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
value , rust_value
) ) ;
}
2023-04-21 22:04:22 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 22:04:22 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 22:04:22 -04:00
}
2023-04-21 22:23:59 -04:00
2023-10-02 12:28:48 -04:00
fn compare_horizontal_rule < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b HorizontalRule < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 22:23:59 -04:00
let child_status = Vec ::new ( ) ;
2023-10-04 20:01:09 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-04-21 22:23:59 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 22:23:59 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 22:23:59 -04:00
}
2023-04-21 22:33:10 -04:00
2023-10-02 12:28:48 -04:00
fn compare_keyword < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Keyword < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-21 22:33:10 -04:00
let child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
2023-08-29 21:05:51 -04:00
let mut message = None ;
2023-04-21 22:33:10 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-09-06 12:08:06 -04:00
let key = unquote (
get_property ( emacs , " :key " ) ?
. ok_or ( " Emacs keywords should have a :key " ) ?
. as_atom ( ) ? ,
) ? ;
if key ! = rust . key . to_uppercase ( ) {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Mismatchs keyword keys (emacs != rust) {:?} != {:?} " ,
key , rust . key
) )
}
let value = unquote (
get_property ( emacs , " :value " ) ?
. ok_or ( " Emacs keywords should have a :value " ) ?
. as_atom ( ) ? ,
) ? ;
if value ! = rust . value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Mismatchs keyword values (emacs != rust) {:?} != {:?} " ,
value , rust . value
) )
}
2023-09-04 19:17:23 -04:00
2023-09-06 18:04:53 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-09-06 18:04:53 -04:00
message ,
children : child_status ,
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
}
. into ( ) )
}
2023-10-02 12:28:48 -04:00
fn compare_babel_call < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b BabelCall < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-09-06 18:04:53 -04:00
let child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-10-05 16:27:36 -04:00
// Compare value
2023-10-05 16:32:40 -04:00
let value = get_property_quoted_string ( emacs , " :value " ) ? . unwrap_or ( String ::new ( ) ) ;
2023-09-06 18:04:53 -04:00
if value ! = rust . value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
2023-10-05 16:32:40 -04:00
" Value mismatch (emacs != rust) {:?} != {:?} " ,
2023-09-06 18:04:53 -04:00
value , rust . value
) )
}
2023-10-05 16:32:40 -04:00
// Compare call
let call = get_property_quoted_string ( emacs , " :call " ) ? ;
if call . as_ref ( ) . map ( String ::as_str ) ! = rust . call {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Call mismatch (emacs != rust) {:?} != {:?} " ,
call , rust . call
) )
}
// Compare arguments
let arguments = get_property_quoted_string ( emacs , " :arguments " ) ? ;
if arguments . as_ref ( ) . map ( String ::as_str ) ! = rust . arguments {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Arguments mismatch (emacs != rust) {:?} != {:?} " ,
arguments , rust . arguments
) )
}
// Compare inside header
let inside_header = get_property_quoted_string ( emacs , " :inside-header " ) ? ;
if inside_header . as_ref ( ) . map ( String ::as_str ) ! = rust . inside_header {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Inside header mismatch (emacs != rust) {:?} != {:?} " ,
inside_header , rust . inside_header
) )
}
// Compare end header
let end_header = get_property_quoted_string ( emacs , " :end-header " ) ? ;
if end_header . as_ref ( ) . map ( String ::as_str ) ! = rust . end_header {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" End header mismatch (emacs != rust) {:?} != {:?} " ,
end_header , rust . end_header
) )
}
2023-04-21 22:33:10 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-21 22:33:10 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-21 22:33:10 -04:00
}
2023-04-22 16:56:36 -04:00
2023-10-02 12:28:48 -04:00
fn compare_latex_environment < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b LatexEnvironment < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-22 16:56:36 -04:00
let child_status = Vec ::new ( ) ;
2023-10-04 20:01:09 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-04-22 16:56:36 -04:00
2023-10-05 01:06:30 -04:00
// TODO: Compare :caption
2023-10-04 20:01:09 -04:00
// 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
) ) ;
}
2023-10-05 20:13:10 -04:00
// Compare value
let value = get_property_quoted_string ( emacs , " :value " ) ? ;
2023-10-06 11:45:15 -04:00
if value . as_ref ( ) . map ( String ::as_str ) ! = Some ( rust . value ) {
2023-10-05 20:13:10 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Value mismatch (emacs != rust) {:?} != {:?} " ,
2023-10-06 11:45:15 -04:00
value , rust . value
2023-10-05 20:13:10 -04:00
) ) ;
}
2023-04-22 16:56:36 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-04-22 16:56:36 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 16:56:36 -04:00
}
2023-04-22 17:58:16 -04:00
2023-10-02 12:28:48 -04:00
fn compare_plain_text < ' b , ' s > (
2023-04-22 17:58:16 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b PlainText < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-04-22 17:58:16 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-08-29 19:22:11 -04:00
let rust_source = rust . get_source ( ) ;
2023-04-22 17:58:16 -04:00
let text = emacs . as_text ( ) ? ;
2023-04-24 18:55:15 -04:00
let start_ind : usize = text
. properties
. get ( 0 )
. expect ( " Should have start index. " )
. as_atom ( ) ?
. parse ( ) ? ;
let end_ind : usize = text
. properties
. get ( 1 )
. expect ( " Should have end index. " )
. as_atom ( ) ?
. parse ( ) ? ;
let emacs_text_length = end_ind - start_ind ;
2023-08-31 20:19:28 -04:00
if rust_source . chars ( ) . count ( ) ! = emacs_text_length {
2023-04-24 18:21:38 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" (emacs len != rust len) {:?} != {:?} " ,
2023-04-24 18:55:15 -04:00
emacs_text_length ,
2023-08-29 19:22:11 -04:00
rust_source . len ( )
2023-04-24 18:21:38 -04:00
) ) ;
}
2023-08-25 06:46:00 -04:00
let unquoted_text = unquote ( text . text ) ? ;
2023-08-29 19:22:11 -04:00
if unquoted_text ! = rust_source {
2023-04-22 17:58:16 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" (emacs != rust) {:?} != {:?} " ,
2023-08-29 19:22:11 -04:00
unquoted_text , rust_source
2023-04-22 17:58:16 -04:00
) ) ;
}
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-04-22 17:58:16 -04:00
message ,
children : Vec ::new ( ) ,
2023-08-29 19:22:11 -04:00
rust_source ,
2023-08-29 14:40:58 -04:00
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 17:58:16 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_bold < ' b , ' s > (
2023-10-06 12:12:24 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Bold < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 13:45:19 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-06 12:12:24 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 13:45:19 -04:00
let mut message = None ;
2023-10-09 13:08:45 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! ( emacs ) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 13:45:19 -04:00
}
2023-04-22 20:48:01 -04:00
2023-04-22 17:58:16 -04:00
Ok ( DiffResult {
2023-04-22 20:48:01 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 20:22:07 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_italic < ' b , ' s > (
2023-10-06 12:12:24 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Italic < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 16:32:49 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-06 12:12:24 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 16:32:49 -04:00
let mut message = None ;
2023-10-09 13:08:45 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! ( emacs ) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 16:32:49 -04:00
}
2023-04-22 20:48:01 -04:00
2023-04-22 20:22:07 -04:00
Ok ( DiffResult {
2023-04-22 20:48:01 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 20:22:07 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_underline < ' b , ' s > (
2023-10-06 12:12:24 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Underline < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 16:32:49 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-06 12:12:24 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 16:32:49 -04:00
let mut message = None ;
2023-10-09 13:08:45 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! ( emacs ) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 16:32:49 -04:00
}
2023-04-22 20:48:01 -04:00
2023-04-22 20:22:07 -04:00
Ok ( DiffResult {
2023-04-22 20:48:01 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 20:22:07 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_verbatim < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Verbatim < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 12:12:24 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 12:12:24 -04:00
let mut message = None ;
2023-04-22 20:48:01 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-06 13:40:11 -04:00
emacs ,
2023-10-06 16:03:41 -04:00
rust ,
2023-10-06 16:19:43 -04:00
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . contents ) ,
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 12:12:24 -04:00
}
2023-09-23 14:46:36 -04:00
2023-04-22 20:22:07 -04:00
Ok ( DiffResult {
2023-04-22 20:48:01 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 20:22:07 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_code < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Code < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 12:12:24 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 12:12:24 -04:00
let mut message = None ;
2023-04-22 20:48:01 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-06 13:29:46 -04:00
emacs ,
2023-10-06 16:03:41 -04:00
rust ,
2023-10-06 16:19:43 -04:00
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . contents ) ,
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 13:29:46 -04:00
}
2023-10-06 13:08:15 -04:00
2023-04-22 20:22:07 -04:00
Ok ( DiffResult {
2023-04-22 20:48:01 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 20:22:07 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_strike_through < ' b , ' s > (
2023-10-06 12:12:24 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b StrikeThrough < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 16:32:49 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-06 12:12:24 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 16:32:49 -04:00
let mut message = None ;
2023-10-09 13:08:45 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! ( emacs ) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 16:32:49 -04:00
}
2023-04-22 20:48:01 -04:00
2023-04-22 20:22:07 -04:00
Ok ( DiffResult {
2023-04-22 20:48:01 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 17:58:16 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_regular_link < ' b , ' s > (
2023-10-07 00:57:55 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b RegularLink < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-06 16:42:31 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-07 00:57:55 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-06 16:42:31 -04:00
let mut message = None ;
2023-04-23 16:17:52 -04:00
2023-10-09 13:08:45 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-06 16:42:31 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :type " ) ,
2023-10-06 17:28:26 -04:00
| r | {
2023-10-06 22:08:26 -04:00
match & r . link_type {
LinkType ::File = > Some ( Cow ::Borrowed ( " file " ) ) ,
LinkType ::Protocol ( protocol ) = > Some ( protocol . clone ( ) ) ,
LinkType ::Id = > Some ( Cow ::Borrowed ( " id " ) ) ,
LinkType ::CustomId = > Some ( Cow ::Borrowed ( " custom-id " ) ) ,
LinkType ::CodeRef = > Some ( Cow ::Borrowed ( " coderef " ) ) ,
LinkType ::Fuzzy = > Some ( Cow ::Borrowed ( " fuzzy " ) ) ,
2023-10-06 17:28:26 -04:00
}
} ,
compare_property_quoted_string
2023-10-06 16:42:31 -04:00
) ,
(
EmacsField ::Required ( " :path " ) ,
2023-10-06 18:30:08 -04:00
| r | Some ( r . get_path ( ) ) ,
2023-10-06 19:49:06 -04:00
compare_property_quoted_string
2023-10-06 16:42:31 -04:00
) ,
(
EmacsField ::Required ( " :format " ) ,
2023-10-06 18:30:08 -04:00
| _ | Some ( " bracket " ) ,
compare_property_unquoted_atom
2023-10-06 16:42:31 -04:00
) ,
(
EmacsField ::Required ( " :raw-link " ) ,
2023-10-06 18:30:08 -04:00
| r | Some ( r . get_raw_link ( ) ) ,
2023-10-06 19:49:06 -04:00
compare_property_quoted_string
2023-10-06 16:42:31 -04:00
) ,
(
EmacsField ::Required ( " :application " ) ,
2023-10-07 03:14:16 -04:00
| r | r . application . as_ref ( ) ,
compare_property_quoted_string
2023-10-06 16:42:31 -04:00
) ,
(
EmacsField ::Required ( " :search-option " ) ,
2023-10-06 19:05:56 -04:00
| r | r . get_search_option ( ) ,
2023-10-06 19:49:06 -04:00
compare_property_quoted_string
2023-10-06 16:42:31 -04:00
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-06 16:42:31 -04:00
}
2023-09-14 02:58:57 -04:00
2023-04-22 17:58:16 -04:00
Ok ( DiffResult {
2023-04-23 16:17:52 -04:00
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-22 17:58:16 -04:00
}
2023-04-24 18:55:15 -04:00
2023-10-02 12:28:48 -04:00
fn compare_radio_link < ' b , ' s > (
2023-10-07 00:57:55 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b RadioLink < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-07 00:57:55 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-04-24 18:55:15 -04:00
2023-10-09 13:08:45 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-07 00:57:55 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :type " ) ,
| _ | { Some ( " radio " ) } ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :path " ) ,
| r | Some ( & r . path ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :format " ) ,
| _ | Some ( " plain " ) ,
compare_property_unquoted_atom
) ,
(
EmacsField ::Required ( " :raw-link " ) ,
2023-10-07 01:46:22 -04:00
| r | Some ( r . get_raw_link ( ) ) ,
2023-10-07 00:57:55 -04:00
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :application " ) ,
compare_identity ,
compare_property_always_nil
) ,
(
EmacsField ::Required ( " :search-option " ) ,
compare_identity ,
compare_property_always_nil
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-07 00:57:55 -04:00
}
2023-04-24 18:55:15 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-24 18:55:15 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_radio_target < ' b , ' s > (
2023-10-07 01:24:32 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b RadioTarget < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-07 01:24:32 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-04-24 18:55:15 -04:00
2023-10-09 13:00:47 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-07 01:24:32 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . value ) ,
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-07 01:24:32 -04:00
}
2023-04-24 18:55:15 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-04-24 18:55:15 -04:00
}
2023-07-13 18:18:07 -04:00
2023-10-02 12:28:48 -04:00
fn compare_plain_link < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b PlainLink < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-07 02:22:36 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-07 02:22:36 -04:00
let mut message = None ;
2023-07-13 18:18:07 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-07 02:22:36 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :type " ) ,
| r | {
match & r . link_type {
LinkType ::File = > Some ( Cow ::Borrowed ( " file " ) ) ,
LinkType ::Protocol ( protocol ) = > Some ( protocol . clone ( ) ) ,
LinkType ::Id = > Some ( Cow ::Borrowed ( " id " ) ) ,
LinkType ::CustomId = > Some ( Cow ::Borrowed ( " custom-id " ) ) ,
LinkType ::CodeRef = > Some ( Cow ::Borrowed ( " coderef " ) ) ,
LinkType ::Fuzzy = > Some ( Cow ::Borrowed ( " fuzzy " ) ) ,
}
} ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :path " ) ,
| r | Some ( r . path ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :format " ) ,
| _ | Some ( " plain " ) ,
compare_property_unquoted_atom
) ,
(
EmacsField ::Required ( " :raw-link " ) ,
| r | Some ( r . raw_link ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :application " ) ,
2023-10-07 03:00:40 -04:00
| r | r . application ,
compare_property_quoted_string
2023-10-07 02:22:36 -04:00
) ,
(
EmacsField ::Required ( " :search-option " ) ,
| r | r . search_option ,
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-07 02:22:36 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-13 18:18:07 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-13 18:18:07 -04:00
}
2023-07-13 22:42:42 -04:00
2023-10-02 12:28:48 -04:00
fn compare_angle_link < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b AngleLink < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-08 10:25:44 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-08 10:25:44 -04:00
let mut message = None ;
2023-07-13 22:42:42 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-08 10:25:44 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :type " ) ,
| r | {
match & r . link_type {
LinkType ::File = > Some ( Cow ::Borrowed ( " file " ) ) ,
LinkType ::Protocol ( protocol ) = > Some ( protocol . clone ( ) ) ,
LinkType ::Id = > Some ( Cow ::Borrowed ( " id " ) ) ,
LinkType ::CustomId = > Some ( Cow ::Borrowed ( " custom-id " ) ) ,
LinkType ::CodeRef = > Some ( Cow ::Borrowed ( " coderef " ) ) ,
LinkType ::Fuzzy = > Some ( Cow ::Borrowed ( " fuzzy " ) ) ,
}
} ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :path " ) ,
2023-10-08 13:02:09 -04:00
| r | Some ( r . get_path ( ) ) ,
2023-10-08 10:25:44 -04:00
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :format " ) ,
2023-10-08 12:46:18 -04:00
| _ | Some ( " angle " ) ,
2023-10-08 10:25:44 -04:00
compare_property_unquoted_atom
) ,
(
EmacsField ::Required ( " :raw-link " ) ,
| r | Some ( r . raw_link ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :application " ) ,
| r | r . application ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :search-option " ) ,
2023-10-08 13:23:12 -04:00
| r | r . get_search_option ( ) ,
2023-10-08 10:25:44 -04:00
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-08 10:25:44 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-13 22:42:42 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-13 22:42:42 -04:00
}
2023-07-13 23:26:51 -04:00
2023-10-02 12:28:48 -04:00
fn compare_org_macro < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b OrgMacro < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-08 14:40:01 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-08 14:40:01 -04:00
let mut message = None ;
2023-07-13 23:26:51 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-08 14:40:01 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :key " ) ,
2023-10-08 16:51:44 -04:00
| r | Some ( r . get_key ( ) ) ,
2023-10-08 14:40:01 -04:00
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :value " ) ,
2023-10-08 16:51:44 -04:00
| r | Some ( r . value ) ,
2023-10-08 14:40:01 -04:00
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :args " ) ,
2023-10-08 16:51:44 -04:00
| r | if r . args . is_empty ( ) {
2023-10-08 14:40:01 -04:00
None
} else {
2023-10-08 16:51:44 -04:00
Some ( r . get_args ( ) )
2023-10-08 14:40:01 -04:00
} ,
compare_property_list_of_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-08 14:40:01 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-13 23:26:51 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-13 23:26:51 -04:00
}
2023-07-18 20:05:39 -04:00
2023-10-02 12:28:48 -04:00
fn compare_entity < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Entity < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-08 17:24:03 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-08 17:24:03 -04:00
let mut message = None ;
2023-07-18 20:05:39 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-08 17:24:03 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :name " ) ,
| r | Some ( r . name ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :latex " ) ,
2023-10-08 18:14:48 -04:00
| r | Some ( r . latex ) ,
compare_property_quoted_string
2023-10-08 17:24:03 -04:00
) ,
(
EmacsField ::Required ( " :latex-math-p " ) ,
2023-10-08 18:14:48 -04:00
| r | r . latex_math_mode ,
compare_property_boolean
2023-10-08 17:24:03 -04:00
) ,
(
EmacsField ::Required ( " :html " ) ,
2023-10-08 18:14:48 -04:00
| r | Some ( r . html ) ,
compare_property_quoted_string
2023-10-08 17:24:03 -04:00
) ,
(
EmacsField ::Required ( " :ascii " ) ,
2023-10-08 18:14:48 -04:00
| r | Some ( r . ascii ) ,
compare_property_quoted_string
2023-10-08 17:24:03 -04:00
) ,
(
2023-10-08 18:14:48 -04:00
// latin1... like I give a shit.
2023-10-08 17:24:03 -04:00
EmacsField ::Required ( " :latin1 " ) ,
compare_identity ,
compare_noop
) ,
(
EmacsField ::Required ( " :utf-8 " ) ,
2023-10-08 18:14:48 -04:00
| r | Some ( r . utf8 ) ,
compare_property_quoted_string
2023-10-08 17:24:03 -04:00
) ,
(
EmacsField ::Required ( " :use-brackets-p " ) ,
2023-10-08 18:14:48 -04:00
| r | r . use_brackets ,
compare_property_boolean
2023-10-08 17:24:03 -04:00
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-08 17:24:03 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-18 20:05:39 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-18 20:05:39 -04:00
}
2023-07-18 20:51:06 -04:00
2023-10-02 12:28:48 -04:00
fn compare_latex_fragment < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b LatexFragment < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 12:30:59 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-09 12:30:59 -04:00
let mut message = None ;
2023-07-18 20:51:06 -04:00
2023-10-09 13:08:45 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-09 12:30:59 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . value ) ,
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-09 12:30:59 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-18 20:51:06 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-18 20:51:06 -04:00
}
2023-07-19 00:09:16 -04:00
2023-10-02 12:28:48 -04:00
fn compare_export_snippet < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b ExportSnippet < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 12:34:21 -04:00
let mut this_status = DiffStatus ::Good ;
2023-10-09 15:13:05 -04:00
let mut child_status = Vec ::new ( ) ;
2023-10-09 12:34:21 -04:00
let mut message = None ;
2023-07-19 00:09:16 -04:00
2023-10-09 13:00:47 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-09 12:34:21 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :back-end " ) ,
| r | Some ( r . backend ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :value " ) ,
| r | r . contents ,
compare_property_quoted_string
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-09 12:34:21 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-19 00:09:16 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-19 00:09:16 -04:00
}
2023-07-19 18:56:46 -04:00
2023-10-02 12:28:48 -04:00
fn compare_footnote_reference < ' b , ' s > (
2023-10-09 13:14:35 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b FootnoteReference < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 13:14:35 -04:00
let mut child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-07-19 18:56:46 -04:00
2023-10-09 13:14:35 -04:00
compare_children (
source ,
emacs ,
& rust . definition ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-09 13:14:35 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :label " ) ,
| r | r . label ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :type " ) ,
2023-10-09 13:23:08 -04:00
| r | Some ( match r . get_type ( ) {
FootnoteReferenceType ::Standard = > " standard " ,
FootnoteReferenceType ::Inline = > " inline " ,
} ) ,
2023-10-09 13:14:35 -04:00
compare_property_unquoted_atom
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-09 13:14:35 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-19 18:56:46 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 13:14:35 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-19 18:56:46 -04:00
}
2023-07-20 00:38:16 -04:00
2023-10-02 12:28:48 -04:00
fn compare_citation < ' b , ' s > (
2023-10-09 14:17:37 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Citation < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 14:17:37 -04:00
let mut child_status = Vec ::new ( ) ;
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
2023-07-20 00:38:16 -04:00
2023-10-09 14:17:37 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-09 14:17:37 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :style " ) ,
| r | r . style ,
compare_property_quoted_string
) ,
(
2023-10-09 15:41:21 -04:00
EmacsField ::Optional ( " :prefix " ) ,
| r | if r . prefix . is_empty ( ) {
None
} else {
Some ( r . prefix . iter ( ) )
} ,
2023-10-09 15:13:05 -04:00
compare_property_list_of_ast_nodes
2023-10-09 14:17:37 -04:00
) ,
(
2023-10-09 15:41:21 -04:00
EmacsField ::Optional ( " :suffix " ) ,
| r | if r . suffix . is_empty ( ) {
None
} else {
Some ( r . suffix . iter ( ) )
} ,
2023-10-09 15:13:05 -04:00
compare_property_list_of_ast_nodes
2023-10-09 14:17:37 -04:00
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-09 14:17:37 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-20 00:38:16 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-20 00:38:16 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_citation_reference < ' b , ' s > (
2023-10-09 15:13:05 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b CitationReference < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 15:13:05 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-07-20 00:38:16 -04:00
2023-10-09 14:17:37 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-10-09 15:13:05 -04:00
for diff in compare_properties! (
source ,
2023-10-09 14:17:37 -04:00
emacs ,
rust ,
(
EmacsField ::Required ( " :key " ) ,
| r | Some ( r . key ) ,
compare_property_quoted_string
) ,
(
2023-10-09 15:41:21 -04:00
EmacsField ::Optional ( " :prefix " ) ,
| r | if r . prefix . is_empty ( ) {
None
} else {
Some ( r . prefix . iter ( ) )
} ,
2023-10-09 15:13:05 -04:00
compare_property_list_of_ast_nodes
2023-10-09 14:17:37 -04:00
) ,
(
2023-10-09 15:41:21 -04:00
EmacsField ::Optional ( " :suffix " ) ,
| r | if r . suffix . is_empty ( ) {
None
} else {
Some ( r . suffix . iter ( ) )
} ,
2023-10-09 15:13:05 -04:00
compare_property_list_of_ast_nodes
2023-10-09 14:17:37 -04:00
)
2023-10-09 15:13:05 -04:00
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
2023-10-09 14:17:37 -04:00
}
2023-09-23 14:46:36 -04:00
2023-07-20 00:38:16 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 15:13:05 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-20 00:38:16 -04:00
}
2023-07-21 19:53:02 -04:00
2023-10-02 12:28:48 -04:00
fn compare_inline_babel_call < ' b , ' s > (
2023-10-09 19:21:58 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b InlineBabelCall < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:21:58 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-07-21 19:53:02 -04:00
2023-10-09 19:21:58 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :call " ) ,
| r | Some ( r . call ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :inside-header " ) ,
| r | r . inside_header ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :arguments " ) ,
| r | r . arguments ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :end-header " ) ,
| r | r . end_header ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . value ) ,
compare_property_quoted_string
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-09-23 14:46:36 -04:00
2023-07-21 19:53:02 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:21:58 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-21 19:53:02 -04:00
}
2023-07-21 22:29:04 -04:00
2023-10-02 12:28:48 -04:00
fn compare_inline_source_block < ' b , ' s > (
2023-10-09 19:31:57 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b InlineSourceBlock < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:31:57 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
2023-07-21 22:29:04 -04:00
2023-10-09 19:31:57 -04:00
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :language " ) ,
| r | Some ( r . language ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . value ) ,
compare_property_quoted_string
) ,
(
EmacsField ::Required ( " :parameters " ) ,
| r | r . parameters ,
compare_property_quoted_string
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-09-23 14:46:36 -04:00
2023-07-21 22:29:04 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:31:57 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-21 22:29:04 -04:00
}
2023-07-21 23:48:37 -04:00
2023-10-02 12:28:48 -04:00
fn compare_line_break < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b LineBreak < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:33:51 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
for diff in compare_properties! ( emacs ) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-07-21 23:48:37 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:33:51 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-21 23:48:37 -04:00
}
2023-07-22 01:15:04 -04:00
2023-10-02 12:28:48 -04:00
fn compare_target < ' b , ' s > (
2023-10-09 19:37:47 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Target < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:37:47 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-07-22 01:15:04 -04:00
2023-10-09 19:37:47 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . value ) ,
compare_property_quoted_string
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-09-23 14:46:36 -04:00
2023-07-22 01:15:04 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:37:47 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-22 01:15:04 -04:00
}
2023-07-22 01:49:07 -04:00
2023-10-02 12:28:48 -04:00
fn compare_statistics_cookie < ' b , ' s > (
2023-10-09 19:40:13 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b StatisticsCookie < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:40:13 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-07-22 01:49:07 -04:00
2023-10-09 19:40:13 -04:00
assert_no_children ( emacs , & mut this_status , & mut message ) ? ;
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :value " ) ,
| r | Some ( r . value ) ,
compare_property_quoted_string
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-09-23 14:46:36 -04:00
2023-07-22 01:49:07 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:40:13 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-22 01:49:07 -04:00
}
2023-07-24 14:19:19 -04:00
2023-10-02 12:28:48 -04:00
fn compare_subscript < ' b , ' s > (
2023-10-09 19:51:31 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Subscript < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:51:31 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-07-24 14:19:19 -04:00
2023-10-09 19:51:31 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :use-brackets-p " ) ,
| r | r . use_brackets ,
compare_property_boolean
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-09-21 14:30:56 -04:00
2023-07-24 14:19:19 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:51:31 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-24 14:19:19 -04:00
}
2023-10-02 12:28:48 -04:00
fn compare_superscript < ' b , ' s > (
2023-10-09 19:51:31 -04:00
source : & ' s str ,
2023-10-02 12:53:23 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Superscript < ' s > ,
2023-10-02 12:28:48 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error > > {
2023-10-09 19:51:31 -04:00
let mut this_status = DiffStatus ::Good ;
let mut child_status = Vec ::new ( ) ;
let mut message = None ;
2023-07-24 14:19:19 -04:00
2023-10-09 19:51:31 -04:00
compare_children (
source ,
emacs ,
& rust . children ,
& mut child_status ,
& mut this_status ,
& mut message ,
) ? ;
for diff in compare_properties! (
source ,
emacs ,
rust ,
(
EmacsField ::Required ( " :use-brackets-p " ) ,
| r | r . use_brackets ,
compare_property_boolean
)
) {
match diff {
ComparePropertiesResult ::NoChange = > { }
ComparePropertiesResult ::SelfChange ( new_status , new_message ) = > {
this_status = new_status ;
message = new_message
}
ComparePropertiesResult ::DiffEntry ( diff_entry ) = > child_status . push ( diff_entry ) ,
}
}
2023-09-21 14:30:56 -04:00
2023-07-24 14:19:19 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-10-09 19:51:31 -04:00
children : child_status ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-24 14:19:19 -04:00
}
2023-07-24 17:34:07 -04:00
2023-10-02 12:28:48 -04:00
fn compare_timestamp < ' b , ' s > (
2023-09-23 21:03:12 -04:00
_source : & ' s str ,
2023-10-02 12:28:48 -04:00
emacs : & ' b Token < ' s > ,
rust : & ' b Timestamp < ' s > ,
2023-10-02 15:51:29 -04:00
) -> Result < DiffEntry < ' b , ' s > , Box < dyn std ::error ::Error + ' s > > {
2023-10-02 13:33:00 -04:00
let mut this_status = DiffStatus ::Good ;
let mut message = None ;
// Compare type
let timestamp_type = get_property_unquoted_atom ( emacs , " :type " ) ? ;
match ( timestamp_type , & rust . timestamp_type ) {
( Some ( " diary " ) , TimestampType ::Diary ) = > { }
( Some ( " active " ) , TimestampType ::Active ) = > { }
( Some ( " inactive " ) , TimestampType ::Inactive ) = > { }
( Some ( " active-range " ) , TimestampType ::ActiveRange ) = > { }
( Some ( " inactive-range " ) , TimestampType ::InactiveRange ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Timestamp type mismatch (emacs != rust) {:?} != {:?} " ,
timestamp_type , rust . timestamp_type
) ) ;
}
}
2023-10-02 13:42:46 -04:00
2023-10-02 14:45:20 -04:00
// Compare range-type
2023-10-02 13:42:46 -04:00
let range_type = get_property_unquoted_atom ( emacs , " :range-type " ) ? ;
match ( range_type , & rust . range_type ) {
( Some ( " daterange " ) , TimestampRangeType ::DateRange ) = > { }
2023-10-02 17:47:09 -04:00
( Some ( " timerange " ) , TimestampRangeType ::TimeRange ) = > { }
2023-10-02 13:42:46 -04:00
( None , TimestampRangeType ::None ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Range type mismatch (emacs != rust) {:?} != {:?} " ,
range_type , rust . range_type
) ) ;
}
}
2023-07-24 17:34:07 -04:00
2023-10-02 14:45:20 -04:00
// Compare raw-value
let raw_value = get_property_quoted_string ( emacs , " :raw-value " ) ?
. ok_or ( " Timestamps should have a :raw-value. " ) ? ;
2023-10-02 16:32:33 -04:00
if raw_value ! = rust . get_raw_value ( ) {
2023-10-02 14:45:20 -04:00
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Raw value mismatch (emacs != rust) {:?} != {:?} " ,
2023-10-02 16:32:33 -04:00
raw_value ,
rust . get_raw_value ( )
2023-10-02 14:45:20 -04:00
) ) ;
}
2023-10-02 15:49:51 -04:00
// Compare start
2023-10-02 15:59:06 -04:00
let year_start : Option < YearInner > = get_property_numeric ( emacs , " :year-start " ) ? ;
let month_start : Option < MonthInner > = get_property_numeric ( emacs , " :month-start " ) ? ;
let day_of_month_start : Option < DayOfMonthInner > = get_property_numeric ( emacs , " :day-start " ) ? ;
let rust_year_start = rust . start . as_ref ( ) . map ( Date ::get_year ) . map ( Year ::get_value ) ;
let rust_month_start = rust
. start
. as_ref ( )
. map ( Date ::get_month )
. map ( Month ::get_value ) ;
let rust_day_of_month_start = rust
. start
. as_ref ( )
. map ( Date ::get_day_of_month )
. map ( DayOfMonth ::get_value ) ;
if year_start ! = rust_year_start {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" year start mismatch (emacs != rust) {:?} != {:?} " ,
year_start , rust_year_start
) ) ;
}
if month_start ! = rust_month_start {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" month start mismatch (emacs != rust) {:?} != {:?} " ,
month_start , rust_month_start
) ) ;
}
if day_of_month_start ! = rust_day_of_month_start {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" day of month start mismatch (emacs != rust) {:?} != {:?} " ,
day_of_month_start , rust_day_of_month_start
) ) ;
}
2023-10-02 15:49:51 -04:00
// Compare end
2023-10-02 15:59:06 -04:00
let year_end : Option < YearInner > = get_property_numeric ( emacs , " :year-end " ) ? ;
let month_end : Option < MonthInner > = get_property_numeric ( emacs , " :month-end " ) ? ;
let day_of_month_end : Option < DayOfMonthInner > = get_property_numeric ( emacs , " :day-end " ) ? ;
let rust_year_end = rust . end . as_ref ( ) . map ( Date ::get_year ) . map ( Year ::get_value ) ;
let rust_month_end = rust . end . as_ref ( ) . map ( Date ::get_month ) . map ( Month ::get_value ) ;
let rust_day_of_month_end = rust
. end
. as_ref ( )
. map ( Date ::get_day_of_month )
. map ( DayOfMonth ::get_value ) ;
if year_end ! = rust_year_end {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" year end mismatch (emacs != rust) {:?} != {:?} " ,
year_end , rust_year_end
) ) ;
}
if month_end ! = rust_month_end {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" month end mismatch (emacs != rust) {:?} != {:?} " ,
month_end , rust_month_end
) ) ;
}
if day_of_month_end ! = rust_day_of_month_end {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" day of month end mismatch (emacs != rust) {:?} != {:?} " ,
day_of_month_end , rust_day_of_month_end
) ) ;
}
2023-10-02 15:49:51 -04:00
2023-10-02 16:32:33 -04:00
// Compare time start
let hour_start : Option < HourInner > = get_property_numeric ( emacs , " :hour-start " ) ? ;
let minute_start : Option < MinuteInner > = get_property_numeric ( emacs , " :minute-start " ) ? ;
2023-10-02 16:37:23 -04:00
let rust_hour_start = rust
. start_time
. as_ref ( )
. map ( Time ::get_hour )
. map ( Hour ::get_value ) ;
let rust_minute_start = rust
. start_time
. as_ref ( )
. map ( Time ::get_minute )
. map ( Minute ::get_value ) ;
if hour_start ! = rust_hour_start {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" hour start mismatch (emacs != rust) {:?} != {:?} " ,
hour_start , rust_hour_start
) ) ;
}
if minute_start ! = rust_minute_start {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" minute start mismatch (emacs != rust) {:?} != {:?} " ,
minute_start , rust_minute_start
) ) ;
}
// Compare time end
let hour_end : Option < HourInner > = get_property_numeric ( emacs , " :hour-end " ) ? ;
let minute_end : Option < MinuteInner > = get_property_numeric ( emacs , " :minute-end " ) ? ;
let rust_hour_end = rust
. end_time
. as_ref ( )
. map ( Time ::get_hour )
. map ( Hour ::get_value ) ;
let rust_minute_end = rust
. end_time
. as_ref ( )
. map ( Time ::get_minute )
. map ( Minute ::get_value ) ;
if hour_end ! = rust_hour_end {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" hour end mismatch (emacs != rust) {:?} != {:?} " ,
hour_end , rust_hour_end
) ) ;
}
if minute_end ! = rust_minute_end {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" minute end mismatch (emacs != rust) {:?} != {:?} " ,
minute_end , rust_minute_end
) ) ;
}
2023-10-02 16:32:33 -04:00
2023-10-02 18:58:30 -04:00
// Compare repeater
let repeater_type = get_property_unquoted_atom ( emacs , " :repeater-type " ) ? ;
let repeater_value : Option < RepeaterWarningDelayValueType > =
get_property_numeric ( emacs , " :repeater-value " ) ? ;
let repeater_unit = get_property_unquoted_atom ( emacs , " :repeater-unit " ) ? ;
let rust_repeater_type = rust
. repeater
. as_ref ( )
. map ( | repeater | & repeater . repeater_type ) ;
let rust_repeater_value = rust . repeater . as_ref ( ) . map ( | repeater | repeater . value ) ;
let rust_repeater_unit = rust . repeater . as_ref ( ) . map ( | repeater | & repeater . unit ) ;
match ( repeater_type , rust_repeater_type ) {
( Some ( " cumulate " ) , Some ( RepeaterType ::Cumulative ) ) = > { }
( Some ( " catch-up " ) , Some ( RepeaterType ::CatchUp ) ) = > { }
( Some ( " restart " ) , Some ( RepeaterType ::Restart ) ) = > { }
( None , None ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Repeater type mismatch (emacs != rust) {:?} != {:?} " ,
repeater_type , rust_repeater_type
) ) ;
}
}
if repeater_value ! = rust_repeater_value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Repeater value mismatch (emacs != rust) {:?} != {:?} " ,
repeater_value , rust_repeater_value
) ) ;
}
match ( repeater_unit , rust_repeater_unit ) {
( Some ( " hour " ) , Some ( TimeUnit ::Hour ) ) = > { }
( Some ( " day " ) , Some ( TimeUnit ::Day ) ) = > { }
( Some ( " week " ) , Some ( TimeUnit ::Week ) ) = > { }
( Some ( " month " ) , Some ( TimeUnit ::Month ) ) = > { }
( Some ( " year " ) , Some ( TimeUnit ::Year ) ) = > { }
( None , None ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Repeater unit mismatch (emacs != rust) {:?} != {:?} " ,
repeater_unit , rust_repeater_unit
) ) ;
}
}
// Compare warning_delay
let warning_delay_type = get_property_unquoted_atom ( emacs , " :warning-type " ) ? ;
let warning_delay_value : Option < RepeaterWarningDelayValueType > =
get_property_numeric ( emacs , " :warning-value " ) ? ;
let warning_delay_unit = get_property_unquoted_atom ( emacs , " :warning-unit " ) ? ;
let rust_warning_delay_type = rust
. warning_delay
. as_ref ( )
. map ( | warning_delay | & warning_delay . warning_delay_type ) ;
let rust_warning_delay_value = rust
. warning_delay
. as_ref ( )
. map ( | warning_delay | warning_delay . value ) ;
let rust_warning_delay_unit = rust
. warning_delay
. as_ref ( )
. map ( | warning_delay | & warning_delay . unit ) ;
match ( warning_delay_type , rust_warning_delay_type ) {
( Some ( " all " ) , Some ( WarningDelayType ::All ) ) = > { }
( Some ( " first " ) , Some ( WarningDelayType ::First ) ) = > { }
( None , None ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Warning delay type mismatch (emacs != rust) {:?} != {:?} " ,
warning_delay_type , rust_warning_delay_type
) ) ;
}
}
if warning_delay_value ! = rust_warning_delay_value {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Warning delay value mismatch (emacs != rust) {:?} != {:?} " ,
warning_delay_value , rust_warning_delay_value
) ) ;
}
match ( warning_delay_unit , rust_warning_delay_unit ) {
( Some ( " hour " ) , Some ( TimeUnit ::Hour ) ) = > { }
( Some ( " day " ) , Some ( TimeUnit ::Day ) ) = > { }
( Some ( " week " ) , Some ( TimeUnit ::Week ) ) = > { }
( Some ( " month " ) , Some ( TimeUnit ::Month ) ) = > { }
( Some ( " year " ) , Some ( TimeUnit ::Year ) ) = > { }
( None , None ) = > { }
_ = > {
this_status = DiffStatus ::Bad ;
message = Some ( format! (
" Warning delay unit mismatch (emacs != rust) {:?} != {:?} " ,
warning_delay_unit , rust_warning_delay_unit
) ) ;
}
}
2023-09-23 14:46:36 -04:00
2023-07-24 17:34:07 -04:00
Ok ( DiffResult {
status : this_status ,
2023-09-23 21:03:12 -04:00
name : rust . get_elisp_name ( ) ,
2023-08-29 21:05:51 -04:00
message ,
2023-07-24 17:34:07 -04:00
children : Vec ::new ( ) ,
2023-08-29 14:40:58 -04:00
rust_source : rust . get_source ( ) ,
emacs_token : emacs ,
2023-08-29 22:47:40 -04:00
}
. into ( ) )
2023-07-24 17:34:07 -04:00
}