Skip to content

Commit

Permalink
Introduce HasSpan trait (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
scouten authored Dec 30, 2023
1 parent 83d2722 commit c52f352
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 17 deletions.
11 changes: 9 additions & 2 deletions src/blocks/block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nom::IResult;

use super::SimpleBlock;
use crate::{primitives::consume_empty_lines, Span};
use crate::{primitives::consume_empty_lines, HasSpan, Span};

/// Block elements form the main structure of an AsciiDoc document, starting
/// with the document itself.
Expand All @@ -20,7 +20,6 @@ pub enum Block<'a> {
}

impl<'a> Block<'a> {
#[allow(dead_code)]
/// Parse a block of any type and return a `Block` that describes it.
///
/// Consumes any blank lines before and after the block.
Expand All @@ -33,3 +32,11 @@ impl<'a> Block<'a> {
Ok((rem, Self::Simple(simple_block)))
}
}

impl<'a> HasSpan<'a> for Block<'a> {
fn span(&'a self) -> &'a Span<'a> {
match self {
Self::Simple(b) => b.span(),
}
}
}
21 changes: 15 additions & 6 deletions src/blocks/simple.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
use nom::{multi::many1, IResult};

use crate::{
primitives::{consume_empty_lines, non_empty_line},
Span,
primitives::{consume_empty_lines, non_empty_line, trim_input_for_rem},
HasSpan, Span,
};

/// A block that's treated as contiguous lines of paragraph text (and subject to
/// normal substitutions) (e.g., a paragraph block).
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SimpleBlock<'a> {
/// Lines that were found.
/// TO DO: Make private
pub inlines: Vec<Span<'a>>,

source: Span<'a>,
}

impl<'a> SimpleBlock<'a> {
#[allow(dead_code)] // TEMPORARY
pub(crate) fn parse(i: Span<'a>) -> IResult<Span, Self> {
let (i, inlines) = many1(non_empty_line)(i)?;
Ok((consume_empty_lines(i), Self { inlines }))
pub(crate) fn parse(source: Span<'a>) -> IResult<Span, Self> {
let (rem, inlines) = many1(non_empty_line)(source)?;
let source = trim_input_for_rem(source, rem);
Ok((consume_empty_lines(rem), Self { inlines, source }))
}
}

impl<'a> HasSpan<'a> for SimpleBlock<'a> {
fn span(&'a self) -> &'a Span<'a> {
&self.source
}
}
13 changes: 7 additions & 6 deletions src/document/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::slice::Iter;

use nom::IResult;

use crate::{blocks::Block, primitives::consume_empty_lines, Error, Span};
use crate::{blocks::Block, primitives::consume_empty_lines, Error, HasSpan, Span};

/// A document represents the top-level block element in AsciiDoc. It consists
/// of an optional document header and either a) one or more sections preceded
Expand Down Expand Up @@ -38,17 +38,18 @@ impl<'a> Document<'a> {
Ok(Self { source, blocks })
}

/// Return a [`Span`] describing the entire document as parsed.
pub fn span(&'a self) -> &'a Span<'a> {
&self.source
}

/// Return an iterator over the blocks in this document.
pub fn blocks(&'a self) -> Iter<'a, Block<'a>> {
self.blocks.iter()
}
}

impl<'a> HasSpan<'a> for Document<'a> {
fn span(&'a self) -> &'a Span<'a> {
&self.source
}
}

fn parse_blocks<'a>(mut i: Span<'a>) -> IResult<Span, Vec<Block<'a>>> {
let mut blocks: Vec<Block<'a>> = vec![];
i = consume_empty_lines(i);
Expand Down
9 changes: 9 additions & 0 deletions src/has_span.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::Span;

/// Any syntactic element can describe its location
/// within the source material using this trait.
pub trait HasSpan<'a> {
/// Return a [`Span`] describing the syntactic element's
/// location within the source string/file.
fn span(&'a self) -> &'a Span<'a>;
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ pub mod document;
mod error;
pub use error::{Error, ParseResult};

mod has_span;
pub use has_span::HasSpan;

pub(crate) mod primitives;
pub use primitives::Span;
pub mod strings;
Expand Down
18 changes: 18 additions & 0 deletions src/tests/asciidoc_lang/root/document_structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ mod documents {
col: 1,
offset: 0,
},],
source: TSpan {
data: "This is a basic AsciiDoc document.\n",
line: 1,
col: 1,
offset: 0,
}
})],
}
);
Expand Down Expand Up @@ -97,6 +103,12 @@ mod documents {
col: 1,
offset: 0,
},],
source: TSpan {
data: "This is a basic AsciiDoc document.\n",
line: 1,
col: 1,
offset: 0,
}
}),
TBlock::Simple(TSimpleBlock {
inlines: vec![TSpan {
Expand All @@ -105,6 +117,12 @@ mod documents {
col: 1,
offset: 36,
},],
source: TSpan {
data: "This document contains two paragraphs.\n",
line: 3,
col: 1,
offset: 36,
}
})
],
}
Expand Down
52 changes: 50 additions & 2 deletions src/tests/blocks/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod simple {
blocks::{TBlock, TSimpleBlock},
TSpan,
},
Span,
HasSpan, Span,
};

#[test]
Expand Down Expand Up @@ -66,9 +66,25 @@ mod simple {
line: 1,
col: 1,
offset: 0,
}]
}],
source: TSpan {
data: "abc",
line: 1,
col: 1,
offset: 0,
}
})
);

assert_eq!(
block.span(),
TSpan {
data: "abc",
line: 1,
col: 1,
offset: 0,
}
);
}

#[test]
Expand Down Expand Up @@ -102,8 +118,24 @@ mod simple {
offset: 4,
},
],
source: TSpan {
data: "abc\ndef",
line: 1,
col: 1,
offset: 0,
}
})
);

assert_eq!(
block.span(),
TSpan {
data: "abc\ndef",
line: 1,
col: 1,
offset: 0,
}
);
}

#[test]
Expand All @@ -129,7 +161,23 @@ mod simple {
col: 1,
offset: 0,
}],
source: TSpan {
data: "abc\n",
line: 1,
col: 1,
offset: 0,
},
})
);

assert_eq!(
block.span(),
TSpan {
data: "abc\n",
line: 1,
col: 1,
offset: 0,
}
);
}
}
18 changes: 18 additions & 0 deletions src/tests/blocks/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ fn single_line() {
col: 1,
offset: 0,
}],
source: TSpan {
data: "abc",
line: 1,
col: 1,
offset: 0,
}
}
);
}
Expand Down Expand Up @@ -86,6 +92,12 @@ fn multiple_lines() {
offset: 4,
}
],
source: TSpan {
data: "abc\ndef",
line: 1,
col: 1,
offset: 0,
}
}
);
}
Expand Down Expand Up @@ -113,6 +125,12 @@ fn consumes_blank_lines_after() {
col: 1,
offset: 0,
}],
source: TSpan {
data: "abc\n",
line: 1,
col: 1,
offset: 0,
}
}
);
}
18 changes: 18 additions & 0 deletions src/tests/document/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ fn one_simple_block() {
col: 1,
offset: 0,
},],
source: TSpan {
data: "abc",
line: 1,
col: 1,
offset: 0,
}
})],
}
);
Expand All @@ -83,6 +89,12 @@ fn two_simple_blocks() {
col: 1,
offset: 0,
},],
source: TSpan {
data: "abc\n",
line: 1,
col: 1,
offset: 0,
}
}),
TBlock::Simple(TSimpleBlock {
inlines: vec![TSpan {
Expand All @@ -91,6 +103,12 @@ fn two_simple_blocks() {
col: 1,
offset: 5,
},],
source: TSpan {
data: "def",
line: 3,
col: 1,
offset: 5,
}
}),
],
}
Expand Down
8 changes: 7 additions & 1 deletion src/tests/fixtures/blocks/simple.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::fmt;

use crate::{blocks::SimpleBlock, tests::fixtures::TSpan};
use crate::{blocks::SimpleBlock, tests::fixtures::TSpan, HasSpan};

#[derive(Eq, PartialEq)]
pub(crate) struct TSimpleBlock {
pub inlines: Vec<TSpan>,
pub source: TSpan,
}

impl fmt::Debug for TSimpleBlock {
Expand All @@ -14,6 +15,7 @@ impl fmt::Debug for TSimpleBlock {
// differences.
f.debug_struct("SimpleBlock")
.field("inlines", &self.inlines)
.field("source", &self.source)
.finish()
}
}
Expand All @@ -35,6 +37,10 @@ fn tsimple_block_eq(tsimple_block: &TSimpleBlock, simple_block: &SimpleBlock) ->
return false;
}

if &tsimple_block.source != simple_block.span() {
return false;
}

for (tsb_line, sb_line) in tsimple_block
.inlines
.iter()
Expand Down
1 change: 1 addition & 0 deletions src/tests/fixtures/document/tdocument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{cmp::PartialEq, fmt};
use crate::{
document::Document,
tests::fixtures::{blocks::TBlock, TSpan},
HasSpan,
};

// Approximate mock of Document type that we can use
Expand Down

0 comments on commit c52f352

Please sign in to comment.