Move the wrapped input into the parser.
This commit is contained in:
parent
65b87bd65d
commit
cda49c628c
@ -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)?;
|
||||||
|
@ -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;
|
||||||
|
@ -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(), "");
|
Loading…
Reference in New Issue
Block a user