asciidoc_parser/content/
content.rs

1//! Describes the content of a non-compound block after any relevant
2//! [substitutions] have been performed.
3//!
4//! [substitutions]: https://docs.asciidoctor.org/asciidoc/latest/subs/
5
6use crate::{Span, strings::CowStr};
7
8/// Describes the annotated content of a block after any relevant
9/// [substitutions] have been performed.
10///
11/// This is typically used to represent the main body of block types that don't
12/// contain other blocks, such as [`SimpleBlock`] or [`RawDelimitedBlock`].
13///
14/// [substitutions]: https://docs.asciidoctor.org/asciidoc/latest/subs/
15/// [`SimpleBlock`]: crate::blocks::SimpleBlock
16/// [`RawDelimitedBlock`]: crate::blocks::RawDelimitedBlock
17#[derive(Clone, Debug, Eq, PartialEq)]
18pub struct Content<'src> {
19    /// The original [`Span`] from which this content was derived.
20    original: Span<'src>,
21
22    /// The possibly-modified text after substititions have been performed.
23    pub(crate) rendered: CowStr<'src>,
24}
25
26impl<'src> Content<'src> {
27    /// Constructs a `Content` from a source `Span` and a potentially-filtered
28    /// view of that source text.
29    pub(crate) fn from_filtered<T: AsRef<str>>(span: Span<'src>, filtered: T) -> Self {
30        Self {
31            original: span,
32            rendered: filtered.as_ref().to_string().into(),
33        }
34    }
35
36    /// Returns the original span from which this [`Content`] was derived.
37    ///
38    /// This is the source text before any substitions have been applied.
39    pub fn original(&self) -> Span<'src> {
40        self.original
41    }
42
43    /// Returns the final text after all substitutions have been applied.
44    pub fn rendered(&'src self) -> &'src str {
45        self.rendered.as_ref()
46    }
47
48    /// Returns `true` if `self` contains no text.
49    pub fn is_empty(&self) -> bool {
50        self.rendered.as_ref().is_empty()
51    }
52}
53
54impl<'src> From<Span<'src>> for Content<'src> {
55    fn from(span: Span<'src>) -> Self {
56        Self {
57            original: span,
58            rendered: CowStr::from(span.data()),
59        }
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    #![allow(clippy::unwrap_used)]
66
67    mod is_empty {
68        #[test]
69        fn basic_empty_span() {
70            let content = crate::content::Content::from(crate::Span::default());
71            assert!(content.is_empty());
72        }
73
74        #[test]
75        fn basic_non_empty_span() {
76            let content = crate::content::Content::from(crate::Span::new("blah"));
77            assert!(!content.is_empty());
78        }
79    }
80}