vimwiki_core/lang/elements/blocks/
paragraphs.rs

1use crate::{
2    lang::elements::{
3        InlineElement, InlineElementContainer, IntoChildren, Located,
4    },
5    StrictEq,
6};
7use derive_more::{Constructor, Index, IndexMut, IntoIterator};
8use serde::{Deserialize, Serialize};
9use std::iter::FromIterator;
10
11#[derive(
12    Constructor,
13    Clone,
14    Debug,
15    Eq,
16    PartialEq,
17    Index,
18    IndexMut,
19    IntoIterator,
20    Serialize,
21    Deserialize,
22)]
23pub struct Paragraph<'a> {
24    /// Represents the lines of content contained within the paragraph
25    #[index]
26    #[index_mut]
27    #[into_iterator(owned, ref, ref_mut)]
28    pub lines: Vec<InlineElementContainer<'a>>,
29}
30
31impl<'a> Paragraph<'a> {
32    /// Returns true if the paragraph only contains blank lines (or has no
33    /// lines at all)
34    pub fn is_blank(&self) -> bool {
35        self.nonblank_lines().count() == 0
36    }
37
38    /// Returns an iterator over all lines that are not blank, meaning that
39    /// they contain non-comment inline elements
40    pub fn nonblank_lines(
41        &self,
42    ) -> impl Iterator<Item = &InlineElementContainer<'a>> {
43        self.into_iter().filter(|line| {
44            line.into_iter()
45                .any(|e| !matches!(e.as_inner(), InlineElement::Comment(_)))
46        })
47    }
48}
49
50impl Paragraph<'_> {
51    pub fn to_borrowed(&self) -> Paragraph {
52        Paragraph::new(self.into_iter().map(|x| x.to_borrowed()).collect())
53    }
54
55    pub fn into_owned(self) -> Paragraph<'static> {
56        Paragraph::new(self.into_iter().map(|x| x.into_owned()).collect())
57    }
58}
59
60impl<'a> IntoChildren for Paragraph<'a> {
61    type Child = Located<InlineElement<'a>>;
62
63    fn into_children(self) -> Vec<Self::Child> {
64        self.into_iter().flat_map(|x| x.into_children()).collect()
65    }
66}
67
68impl<'a> FromIterator<InlineElementContainer<'a>> for Paragraph<'a> {
69    fn from_iter<I: IntoIterator<Item = InlineElementContainer<'a>>>(
70        iter: I,
71    ) -> Self {
72        Self::new(iter.into_iter().collect())
73    }
74}
75
76impl<'a> StrictEq for Paragraph<'a> {
77    /// Performs strict_eq on content
78    fn strict_eq(&self, other: &Self) -> bool {
79        self.lines.strict_eq(&other.lines)
80    }
81}