Initial return and printing of tree diff output.
This commit is contained in:
		
							parent
							
								
									be2d0141a5
								
							
						
					
					
						commit
						6e62bd5ff2
					
				| @ -1,25 +1,123 @@ | ||||
| use super::sexp::Token; | ||||
| use crate::parser::Document; | ||||
| use crate::parser::Section; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct DiffResult { | ||||
|     status: DiffStatus, | ||||
|     name: String, | ||||
|     children: Vec<DiffResult>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum DiffStatus { | ||||
|     Good, | ||||
|     ChildBad, | ||||
|     Bad, | ||||
| } | ||||
| 
 | ||||
| impl DiffResult { | ||||
|     pub fn print(&self) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         self.print_indented(0) | ||||
|     } | ||||
| 
 | ||||
|     fn print_indented(&self, indentation: usize) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         println!( | ||||
|             "{}{:?} {}", | ||||
|             "  ".repeat(indentation), | ||||
|             self.status, | ||||
|             self.name | ||||
|         ); | ||||
|         for child in self.children.iter() { | ||||
|             child.print_indented(indentation + 1)?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn compare_document<'s>( | ||||
|     emacs: &'s Token<'s>, | ||||
|     rust: &'s Document<'s>, | ||||
| ) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     compare_document_indented(0, emacs, rust) | ||||
| } | ||||
| 
 | ||||
| fn compare_document_indented<'s>( | ||||
|     indentation: usize, | ||||
|     emacs: &'s Token<'s>, | ||||
|     rust: &'s Document<'s>, | ||||
| ) -> Result<(), Box<dyn std::error::Error>> { | ||||
| ) -> Result<DiffResult, Box<dyn std::error::Error>> { | ||||
|     let children = emacs.as_list()?; | ||||
|     let first_child = children.first().ok_or("Should have at least one child")?; | ||||
|     let first_child = children.first().ok_or("Should have at least one child.")?; | ||||
|     let first_child_text = first_child.as_atom()?; | ||||
|     if first_child_text != "org-data" { | ||||
|         return Err("Document should correspond to an org-data cell.".into()); | ||||
|     } | ||||
|     let mut child_status = Vec::new(); | ||||
|     // TODO: compare the children
 | ||||
| 
 | ||||
|     Ok(()) | ||||
|     // Skipping "org-data" and the first parameter which is often nil
 | ||||
|     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()); | ||||
|             } | ||||
|             child_status.push(compare_section( | ||||
|                 token, | ||||
|                 rust.zeroth_section | ||||
|                     .as_ref() | ||||
|                     .ok_or("No corresponding zeroth-section")?, | ||||
|             )?); | ||||
|         } 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.")?; | ||||
|             child_status.push(compare_heading(token, rust)?); | ||||
|         } else { | ||||
|             return Err("Document should only contain sections and headlines.".into()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Ok(DiffResult { | ||||
|         status: DiffStatus::Good, | ||||
|         name: "document".to_owned(), | ||||
|         children: child_status, | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| pub fn compare_section<'s>( | ||||
|     emacs: &'s Token<'s>, | ||||
|     rust: &'s Section<'s>, | ||||
| ) -> Result<DiffResult, Box<dyn std::error::Error>> { | ||||
|     let children = emacs.as_list()?; | ||||
|     let first_child = children.first().ok_or("Should have at least one child.")?; | ||||
|     let first_child_text = first_child.as_atom()?; | ||||
|     if first_child_text != "section" { | ||||
|         return Err("Section should correspond to a section cell.".into()); | ||||
|     } | ||||
|     let mut child_status = Vec::new(); | ||||
| 
 | ||||
|     Ok(DiffResult { | ||||
|         status: DiffStatus::Good, | ||||
|         name: "section".to_owned(), | ||||
|         children: child_status, | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| pub fn compare_heading<'s>( | ||||
|     emacs: &'s Token<'s>, | ||||
|     rust: &'s Document<'s>, | ||||
| ) -> Result<DiffResult, Box<dyn std::error::Error>> { | ||||
|     let children = emacs.as_list()?; | ||||
|     let first_child = children.first().ok_or("Should have at least one child.")?; | ||||
|     let first_child_text = first_child.as_atom()?; | ||||
|     if first_child_text != "headline" { | ||||
|         return Err("Heading should correspond to a headline cell.".into()); | ||||
|     } | ||||
|     let mut child_status = Vec::new(); | ||||
| 
 | ||||
|     Ok(DiffResult { | ||||
|         status: DiffStatus::Good, | ||||
|         name: "heading".to_owned(), | ||||
|         children: child_status, | ||||
|     }) | ||||
| } | ||||
|  | ||||
| @ -20,8 +20,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||
|         println!("{:#?}", parsed_sexp); | ||||
|         let (_remaining, rust_parsed) = document(org_contents.as_str()).expect("Org Parse failure"); | ||||
|         println!("{:#?}", rust_parsed); | ||||
|         compare_document(&parsed_sexp, &rust_parsed)?; | ||||
|         let diff_result = compare_document(&parsed_sexp, &rust_parsed)?; | ||||
|         diff_result.print()?; | ||||
|     } | ||||
|     println!("Done."); | ||||
|     shutdown_telemetry()?; | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| @ -16,4 +16,5 @@ mod source; | ||||
| mod util; | ||||
| pub use document::document; | ||||
| pub use document::Document; | ||||
| pub use document::Section; | ||||
| type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander