diff --git a/build.rs b/build.rs index 058a8ee..5d6f10e 100644 --- a/build.rs +++ b/build.rs @@ -74,7 +74,7 @@ fn write_header(test_file: &mut File) { use organic::compare_document; use organic::parser::parse; use organic::emacs_parse_anonymous_org_document; -use organic::parser::sexp::sexp; +use organic::sexp; "# ) diff --git a/src/bin_compare.rs b/src/bin_compare.rs index da41af8..8f91501 100644 --- a/src/bin_compare.rs +++ b/src/bin_compare.rs @@ -10,7 +10,7 @@ use organic::emacs_parse_file_org_document; use organic::get_emacs_version; use organic::get_org_mode_version; use organic::parser::parse_with_settings; -use organic::parser::sexp::sexp; +use organic::sexp; use organic::GlobalSettings; use organic::LocalFileAccessInterface; @@ -66,8 +66,7 @@ fn run_anonymous_parse>(org_contents: P) -> Result<(), Box>(org_path: P) -> Result<(), Box Token<'s> { } } +/// Check if the child string slice is a slice of the parent string slice. +fn is_slice_of(parent: &str, child: &str) -> bool { + let parent_start = parent.as_ptr() as usize; + let parent_end = parent_start + parent.len(); + let child_start = child.as_ptr() as usize; + let child_end = child_start + child.len(); + child_start >= parent_start && child_end <= parent_end +} + +/// Get a slice of the string that was consumed in a parser using the original input to the parser and the remaining input after the parser. +pub fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str { + assert!(is_slice_of(input, remaining)); + let source = { + let offset = remaining.as_ptr() as usize - input.as_ptr() as usize; + &input[..offset] + }; + source.into() +} + pub(crate) fn unquote(text: &str) -> Result> { let mut out = String::with_capacity(text.len()); if !text.starts_with(r#"""#) { @@ -138,21 +154,18 @@ pub(crate) fn unquote(text: &str) -> Result> #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = multispace0(input)?; - let remaining = OrgSource::new(remaining); - let (remaining, tkn) = token(remaining) - .map(|(rem, out)| (Into::<&str>::into(rem), out)) - .map_err(convert_error)?; + let (remaining, tkn) = token(remaining).map(|(rem, out)| (Into::<&str>::into(rem), out))?; let (remaining, _) = multispace0(remaining)?; Ok((remaining, tkn)) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn token<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn token<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { alt((list, vector, atom))(input) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn list<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn list<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = tag("(")(input)?; let (remaining, children) = delimited( multispace0, @@ -164,7 +177,7 @@ fn list<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn vector<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn vector<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = tag("[")(input)?; let (remaining, children) = delimited( multispace0, @@ -176,7 +189,7 @@ fn vector<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn atom<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { not(peek(one_of(")]")))(input)?; alt(( text_with_properties, @@ -187,7 +200,7 @@ fn atom<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn unquoted_atom<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, body) = take_till1(|c| match c { ' ' | '\t' | '\r' | '\n' | ')' | ']' => true, _ => false, @@ -196,7 +209,7 @@ fn unquoted_atom<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn quoted_atom<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn quoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = tag(r#"""#)(input)?; let (remaining, _) = escaped( take_till1(|c| match c { @@ -212,7 +225,7 @@ fn quoted_atom<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn hash_notation<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn hash_notation<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = tag("#<")(input)?; let (remaining, _body) = take_till1(|c| match c { '>' => true, @@ -223,7 +236,7 @@ fn hash_notation<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { Ok((remaining, Token::Atom(source.into()))) } -fn text_with_properties<'s>(input: OrgSource<'s>) -> Res, Token<'s>> { +fn text_with_properties<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, _) = tag("#(")(input)?; let (remaining, (text, props)) = delimited( multispace0, diff --git a/src/compare/util.rs b/src/compare/util.rs index c14a794..4e8668b 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -1,4 +1,4 @@ -use crate::parser::sexp::Token; +use super::sexp::Token; use crate::types::Source; /// Check if the child string slice is a slice of the parent string slice. diff --git a/src/lib.rs b/src/lib.rs index afc3796..bbd1944 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,8 @@ pub use compare::emacs_parse_file_org_document; pub use compare::get_emacs_version; #[cfg(feature = "compare")] pub use compare::get_org_mode_version; +#[cfg(feature = "compare")] +pub use compare::sexp; mod context; mod error; diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6b5b44b..b19f9ca 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -37,8 +37,6 @@ mod property_drawer; mod radio_link; mod regular_link; mod section; -#[cfg(feature = "compare")] -pub mod sexp; mod statistics_cookie; mod subscript_and_superscript; mod table;