Move the wrapped input into the parser.

This commit is contained in:
Tom Alexander 2023-08-22 22:33:50 -04:00
parent 65b87bd65d
commit cda49c628c
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 27 additions and 22 deletions

View File

@ -16,6 +16,7 @@ use nom::sequence::tuple;
use super::element::Element; use super::element::Element;
use super::object::Object; use super::object::Object;
use super::org_source::OrgSource;
use super::parser_with_context::parser_with_context; use super::parser_with_context::parser_with_context;
use super::source::Source; use super::source::Source;
use super::token::AllTokensIterator; use super::token::AllTokensIterator;
@ -95,6 +96,7 @@ impl<'s> Source<'s> for Heading<'s> {
#[allow(dead_code)] #[allow(dead_code)]
pub fn document(input: &str) -> Res<&str, Document> { pub fn document(input: &str) -> Res<&str, Document> {
let initial_context: ContextTree<'_, '_> = ContextTree::new(); let initial_context: ContextTree<'_, '_> = ContextTree::new();
let wrapped_input = OrgSource::new(input);
let document_context = let document_context =
initial_context.with_additional_node(ContextElement::DocumentRoot(input)); initial_context.with_additional_node(ContextElement::DocumentRoot(input));
let (remaining, document) = _document(&document_context, input)?; let (remaining, document) = _document(&document_context, input)?;

View File

@ -30,6 +30,7 @@ mod list;
mod object; mod object;
mod object_parser; mod object_parser;
mod org_macro; mod org_macro;
mod org_source;
mod paragraph; mod paragraph;
mod parser_context; mod parser_context;
mod parser_with_context; mod parser_with_context;

View File

@ -1,21 +1,23 @@
use std::ops::RangeBounds; use std::ops::RangeBounds;
use nom::{Compare, InputTake, Slice}; use nom::Compare;
use nom::InputTake;
use nom::Slice;
#[derive(Debug)] #[derive(Debug)]
struct WrappedInput<'s> { pub struct OrgSource<'s> {
full_source: &'s str, full_source: &'s str,
start: usize, start: usize,
end: usize, //exclusive end: usize, //exclusive
preceding_line_break: Option<usize>, preceding_line_break: Option<usize>,
} }
impl<'s> WrappedInput<'s> { impl<'s> OrgSource<'s> {
/// Returns a wrapped string that keeps track of values we need for parsing org-mode. /// Returns a wrapped string that keeps track of values we need for parsing org-mode.
/// ///
/// Only call this on the full original string. Calling this on a substring can result in invalid values. /// Only call this on the full original string. Calling this on a substring can result in invalid values.
pub fn new(input: &'s str) -> Self { pub fn new(input: &'s str) -> Self {
WrappedInput { OrgSource {
full_source: input, full_source: input,
start: 0, start: 0,
end: input.len(), end: input.len(),
@ -30,7 +32,7 @@ impl<'s> WrappedInput<'s> {
} }
} }
impl<'s> InputTake for WrappedInput<'s> { impl<'s> InputTake for OrgSource<'s> {
fn take(&self, count: usize) -> Self { fn take(&self, count: usize) -> Self {
self.slice(..count) self.slice(..count)
} }
@ -40,7 +42,7 @@ impl<'s> InputTake for WrappedInput<'s> {
} }
} }
impl<'s, O: Into<&'s str>> Compare<O> for WrappedInput<'s> { impl<'s, O: Into<&'s str>> Compare<O> for OrgSource<'s> {
fn compare(&self, t: O) -> nom::CompareResult { fn compare(&self, t: O) -> nom::CompareResult {
(&self.full_source[self.start..self.end]).compare(t.into()) (&self.full_source[self.start..self.end]).compare(t.into())
} }
@ -50,19 +52,19 @@ impl<'s, O: Into<&'s str>> Compare<O> for WrappedInput<'s> {
} }
} }
impl<'s> From<&'s str> for WrappedInput<'s> { impl<'s> From<&'s str> for OrgSource<'s> {
fn from(value: &'s str) -> Self { fn from(value: &'s str) -> Self {
WrappedInput::new(value) OrgSource::new(value)
} }
} }
impl<'s> From<&WrappedInput<'s>> for &'s str { impl<'s> From<&OrgSource<'s>> for &'s str {
fn from(value: &WrappedInput<'s>) -> Self { fn from(value: &OrgSource<'s>) -> Self {
&value.full_source[value.start..value.end] &value.full_source[value.start..value.end]
} }
} }
impl<'s, R> Slice<R> for WrappedInput<'s> impl<'s, R> Slice<R> for OrgSource<'s>
where where
R: RangeBounds<usize>, R: RangeBounds<usize>,
{ {
@ -90,7 +92,7 @@ where
.map(|idx| idx + self.preceding_line_break.unwrap_or(0) + 1); .map(|idx| idx + self.preceding_line_break.unwrap_or(0) + 1);
// TODO: calculate updated values for WrappedInput // TODO: calculate updated values for WrappedInput
WrappedInput { OrgSource {
full_source: self.full_source, full_source: self.full_source,
start: new_start, start: new_start,
end: new_end, end: new_end,
@ -99,7 +101,7 @@ where
} }
} }
impl<'s> std::fmt::Display for WrappedInput<'s> { impl<'s> std::fmt::Display for OrgSource<'s> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
Into::<&str>::into(self).fmt(f) Into::<&str>::into(self).fmt(f)
} }
@ -111,35 +113,35 @@ mod tests {
#[test] #[test]
fn range() { fn range() {
let input = WrappedInput::new("foo bar baz"); let input = OrgSource::new("foo bar baz");
let output = input.slice(4..7); let output = input.slice(4..7);
assert_eq!(output.to_string(), "bar"); assert_eq!(output.to_string(), "bar");
} }
#[test] #[test]
fn range_to() { fn range_to() {
let input = WrappedInput::new("foo bar baz"); let input = OrgSource::new("foo bar baz");
let output = input.slice(..7); let output = input.slice(..7);
assert_eq!(output.to_string(), "foo bar"); assert_eq!(output.to_string(), "foo bar");
} }
#[test] #[test]
fn range_from() { fn range_from() {
let input = WrappedInput::new("foo bar baz"); let input = OrgSource::new("foo bar baz");
let output = input.slice(4..); let output = input.slice(4..);
assert_eq!(output.to_string(), "bar baz"); assert_eq!(output.to_string(), "bar baz");
} }
#[test] #[test]
fn full_range() { fn full_range() {
let input = WrappedInput::new("foo bar baz"); let input = OrgSource::new("foo bar baz");
let output = input.slice(..); let output = input.slice(..);
assert_eq!(output.to_string(), "foo bar baz"); assert_eq!(output.to_string(), "foo bar baz");
} }
#[test] #[test]
fn nested_range() { fn nested_range() {
let input = WrappedInput::new("lorem foo bar baz ipsum"); let input = OrgSource::new("lorem foo bar baz ipsum");
let first_cut = input.slice(6..17); let first_cut = input.slice(6..17);
let output = first_cut.slice(4..7); let output = first_cut.slice(4..7);
assert_eq!(first_cut.to_string(), "foo bar baz"); assert_eq!(first_cut.to_string(), "foo bar baz");
@ -149,21 +151,21 @@ mod tests {
#[test] #[test]
#[should_panic] #[should_panic]
fn out_of_bounds() { fn out_of_bounds() {
let input = WrappedInput::new("lorem foo bar baz ipsum"); let input = OrgSource::new("lorem foo bar baz ipsum");
input.slice(6..30); input.slice(6..30);
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn out_of_nested_bounds() { fn out_of_nested_bounds() {
let input = WrappedInput::new("lorem foo bar baz ipsum"); let input = OrgSource::new("lorem foo bar baz ipsum");
let first_cut = input.slice(6..17); let first_cut = input.slice(6..17);
first_cut.slice(4..14); first_cut.slice(4..14);
} }
#[test] #[test]
fn line_break() { fn line_break() {
let input = WrappedInput::new("lorem\nfoo\nbar\nbaz\nipsum"); let input = OrgSource::new("lorem\nfoo\nbar\nbaz\nipsum");
assert_eq!(input.slice(5..).preceding_line_break, None); assert_eq!(input.slice(5..).preceding_line_break, None);
assert_eq!(input.slice(6..).preceding_line_break, Some(6)); assert_eq!(input.slice(6..).preceding_line_break, Some(6));
assert_eq!(input.slice(6..).slice(10..).preceding_line_break, Some(14)); assert_eq!(input.slice(6..).slice(10..).preceding_line_break, Some(14));
@ -171,7 +173,7 @@ mod tests {
#[test] #[test]
fn text_since_line_break() { fn text_since_line_break() {
let input = WrappedInput::new("lorem\nfoo\nbar\nbaz\nipsum"); let input = OrgSource::new("lorem\nfoo\nbar\nbaz\nipsum");
assert_eq!(input.text_since_line_break(), ""); assert_eq!(input.text_since_line_break(), "");
assert_eq!(input.slice(5..).text_since_line_break(), "lorem"); assert_eq!(input.slice(5..).text_since_line_break(), "lorem");
assert_eq!(input.slice(6..).text_since_line_break(), ""); assert_eq!(input.slice(6..).text_since_line_break(), "");