vimwiki_core/lang/elements/blocks/
mod.rs

1use crate::{
2    lang::elements::{Element, IntoChildren, Located},
3    StrictEq,
4};
5use derive_more::From;
6use serde::{Deserialize, Serialize};
7
8mod blockquotes;
9pub use blockquotes::*;
10mod code;
11pub use code::*;
12mod definitions;
13pub use definitions::*;
14mod dividers;
15pub use dividers::*;
16mod headers;
17pub use headers::*;
18mod inline;
19pub use inline::*;
20mod lists;
21pub use lists::*;
22mod math;
23pub use math::*;
24mod paragraphs;
25pub use paragraphs::*;
26mod placeholders;
27pub use placeholders::*;
28mod tables;
29pub use tables::*;
30
31/// Represents elements that are standalone (metaphorically a block element in CSS)
32#[derive(Clone, Debug, From, Eq, PartialEq, Serialize, Deserialize)]
33pub enum BlockElement<'a> {
34    Blockquote(Blockquote<'a>),
35    CodeBlock(CodeBlock<'a>),
36    DefinitionList(DefinitionList<'a>),
37    Divider(Divider),
38    Header(Header<'a>),
39    List(List<'a>),
40    Math(MathBlock<'a>),
41    Paragraph(Paragraph<'a>),
42    Placeholder(Placeholder<'a>),
43    Table(Table<'a>),
44}
45
46impl BlockElement<'_> {
47    pub fn to_borrowed(&self) -> BlockElement {
48        match self {
49            Self::Blockquote(x) => BlockElement::from(x.to_borrowed()),
50            Self::CodeBlock(x) => BlockElement::from(x.to_borrowed()),
51            Self::DefinitionList(x) => BlockElement::from(x.to_borrowed()),
52            Self::Divider(x) => BlockElement::from(*x),
53            Self::Header(x) => BlockElement::from(x.to_borrowed()),
54            Self::List(x) => BlockElement::from(x.to_borrowed()),
55            Self::Math(x) => BlockElement::from(x.to_borrowed()),
56            Self::Paragraph(x) => BlockElement::from(x.to_borrowed()),
57            Self::Placeholder(x) => BlockElement::from(x.to_borrowed()),
58            Self::Table(x) => BlockElement::from(x.to_borrowed()),
59        }
60    }
61
62    pub fn into_owned(self) -> BlockElement<'static> {
63        match self {
64            Self::Blockquote(x) => BlockElement::Blockquote(x.into_owned()),
65            Self::CodeBlock(x) => BlockElement::CodeBlock(x.into_owned()),
66            Self::DefinitionList(x) => {
67                BlockElement::DefinitionList(x.into_owned())
68            }
69            Self::Divider(x) => BlockElement::Divider(x),
70            Self::Header(x) => BlockElement::Header(x.into_owned()),
71            Self::List(x) => BlockElement::List(x.into_owned()),
72            Self::Math(x) => BlockElement::Math(x.into_owned()),
73            Self::Paragraph(x) => BlockElement::Paragraph(x.into_owned()),
74            Self::Placeholder(x) => BlockElement::Placeholder(x.into_owned()),
75            Self::Table(x) => BlockElement::Table(x.into_owned()),
76        }
77    }
78}
79
80impl<'a> IntoChildren for BlockElement<'a> {
81    type Child = Located<Element<'a>>;
82
83    fn into_children(self) -> Vec<Self::Child> {
84        match self {
85            Self::DefinitionList(x) => x
86                .into_children()
87                .into_iter()
88                .map(|x| x.map(Element::from))
89                .collect(),
90            Self::Header(x) => x
91                .into_children()
92                .into_iter()
93                .map(|x| x.map(Element::from))
94                .collect(),
95            Self::List(x) => x
96                .into_children()
97                .into_iter()
98                .map(|x| x.map(Element::from))
99                .collect(),
100            Self::Paragraph(x) => x
101                .into_children()
102                .into_iter()
103                .map(|x| x.map(Element::from))
104                .collect(),
105            Self::Table(x) => x
106                .into_children()
107                .into_iter()
108                .map(|x| x.map(Element::from))
109                .collect(),
110            _ => vec![],
111        }
112    }
113}
114
115impl<'a> StrictEq for BlockElement<'a> {
116    /// Performs strict_eq check on matching inner variants
117    fn strict_eq(&self, other: &Self) -> bool {
118        match (self, other) {
119            (Self::Blockquote(x), Self::Blockquote(y)) => x.strict_eq(y),
120            (Self::CodeBlock(x), Self::CodeBlock(y)) => x.strict_eq(y),
121            (Self::DefinitionList(x), Self::DefinitionList(y)) => {
122                x.strict_eq(y)
123            }
124            (Self::Divider(x), Self::Divider(y)) => x.strict_eq(y),
125            (Self::Header(x), Self::Header(y)) => x.strict_eq(y),
126            (Self::List(x), Self::List(y)) => x.strict_eq(y),
127            (Self::Math(x), Self::Math(y)) => x.strict_eq(y),
128            (Self::Paragraph(x), Self::Paragraph(y)) => x.strict_eq(y),
129            (Self::Placeholder(x), Self::Placeholder(y)) => x.strict_eq(y),
130            (Self::Table(x), Self::Table(y)) => x.strict_eq(y),
131            _ => false,
132        }
133    }
134}
135
136macro_rules! le_mapping {
137    ($type:ty) => {
138        impl<'a> From<Located<$type>> for Located<BlockElement<'a>> {
139            fn from(element: Located<$type>) -> Self {
140                element.map(BlockElement::from)
141            }
142        }
143    };
144}
145
146le_mapping!(Header<'a>);
147le_mapping!(Paragraph<'a>);
148le_mapping!(DefinitionList<'a>);
149le_mapping!(List<'a>);
150le_mapping!(Table<'a>);
151le_mapping!(CodeBlock<'a>);
152le_mapping!(MathBlock<'a>);
153le_mapping!(Blockquote<'a>);
154le_mapping!(Divider);
155le_mapping!(Placeholder<'a>);