diff --git a/src/compare/diff.rs b/src/compare/diff.rs new file mode 100644 index 0000000..6bd231c --- /dev/null +++ b/src/compare/diff.rs @@ -0,0 +1,25 @@ +use super::sexp::Token; +use crate::parser::Document; + +pub fn compare_document<'s>( + emacs: &'s Token<'s>, + rust: &'s Document<'s>, +) -> Result<(), Box> { + compare_document_indented(0, emacs, rust) +} + +fn compare_document_indented<'s>( + indentation: usize, + emacs: &'s Token<'s>, + rust: &'s Document<'s>, +) -> Result<(), Box> { + 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 != "org-data" { + return Err("Document should correspond to an org-data cell.".into()); + } + // TODO: compare the children + + Ok(()) +} diff --git a/src/compare/mod.rs b/src/compare/mod.rs index d364ed7..4dbb825 100644 --- a/src/compare/mod.rs +++ b/src/compare/mod.rs @@ -1,5 +1,7 @@ +mod diff; mod error; mod parse; mod sexp; +pub use diff::compare_document; pub use parse::emacs_parse_org_document; pub use sexp::sexp; diff --git a/src/compare/sexp.rs b/src/compare/sexp.rs index 4da408d..5257940 100644 --- a/src/compare/sexp.rs +++ b/src/compare/sexp.rs @@ -30,6 +30,22 @@ pub struct TextWithProperties<'s> { properties: Vec>, } +impl<'s> Token<'s> { + pub fn as_list<'p>(&'p self) -> Result<&'p Vec>, Box> { + Ok(match self { + Token::List(children) => Ok(children), + _ => Err("wrong token type"), + }?) + } + + pub fn as_atom<'p>(&'p self) -> Result<&'s str, Box> { + Ok(match self { + Token::Atom(body) => Ok(*body), + _ => Err("wrong token type"), + }?) + } +} + #[tracing::instrument(ret, level = "debug")] pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = multispace0(input)?; diff --git a/src/org_compare.rs b/src/org_compare.rs index 0182ce3..7249f47 100644 --- a/src/org_compare.rs +++ b/src/org_compare.rs @@ -1,18 +1,26 @@ #![feature(round_char_boundary)] #![feature(exit_status_error)] +use crate::compare::compare_document; use crate::init_tracing::init_telemetry; use crate::init_tracing::shutdown_telemetry; +use crate::parser::document; use compare::emacs_parse_org_document; use compare::sexp; mod compare; mod init_tracing; +mod parser; fn main() -> Result<(), Box> { init_telemetry()?; - let org_sexp = emacs_parse_org_document("./org_mode_samples/footnote_definition/simple.org")?; + let org_path = "./org_mode_samples/footnote_definition/simple.org"; + let org_contents = std::fs::read_to_string(org_path)?; + let org_sexp = emacs_parse_org_document(org_path)?; println!("{}", org_sexp); - let parsed_sexp = sexp(org_sexp.as_str()).expect("Parse failure"); + let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).expect("Sexp Parse failure"); 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)?; shutdown_telemetry()?; Ok(()) } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 8f3915e..77672d8 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -15,4 +15,5 @@ mod plain_text; mod source; mod util; pub use document::document; +pub use document::Document; type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;