vimwiki_core/lang/elements/
mod.rs1#![allow(clippy::large_enum_variant)]
2
3use crate::StrictEq;
4use derive_more::{Constructor, From, Index, IndexMut, IntoIterator};
5use serde::{Deserialize, Serialize};
6use std::iter::FromIterator;
7
8mod blocks;
9pub use blocks::*;
10mod utils;
11pub use utils::{
12 AsChildrenMutSlice, AsChildrenSlice, IntoChildren, Located, Region,
13};
14
15#[derive(
17 Constructor,
18 Clone,
19 Debug,
20 Default,
21 Eq,
22 PartialEq,
23 Index,
24 IndexMut,
25 IntoIterator,
26 Serialize,
27 Deserialize,
28)]
29pub struct Page<'a> {
30 #[index]
32 #[index_mut]
33 #[into_iterator(owned, ref, ref_mut)]
34 pub elements: Vec<Located<BlockElement<'a>>>,
35}
36
37impl<'a> Page<'a> {
38 pub fn elements(&self) -> &[Located<BlockElement<'a>>] {
40 &self.elements
41 }
42
43 pub fn into_elements(self) -> Vec<Located<BlockElement<'a>>> {
45 self.elements
46 }
47}
48
49impl Page<'_> {
50 pub fn to_borrowed(&self) -> Page {
51 let elements = self
52 .elements
53 .iter()
54 .map(|x| x.as_ref().map(BlockElement::to_borrowed))
55 .collect();
56
57 Page { elements }
58 }
59
60 pub fn into_owned(self) -> Page<'static> {
61 let elements = self
62 .elements
63 .into_iter()
64 .map(|x| x.map(BlockElement::into_owned))
65 .collect();
66
67 Page { elements }
68 }
69}
70
71impl<'a> IntoChildren for Page<'a> {
72 type Child = Located<BlockElement<'a>>;
73
74 fn into_children(self) -> Vec<Self::Child> {
75 self.elements
76 }
77}
78
79impl<'a> FromIterator<Located<BlockElement<'a>>> for Page<'a> {
80 fn from_iter<I: IntoIterator<Item = Located<BlockElement<'a>>>>(
81 iter: I,
82 ) -> Self {
83 Self {
84 elements: iter.into_iter().collect(),
85 }
86 }
87}
88
89impl<'a> StrictEq for Page<'a> {
90 fn strict_eq(&self, other: &Self) -> bool {
92 self.elements.len() == other.elements.len()
93 && self
94 .elements
95 .iter()
96 .zip(other.elements.iter())
97 .all(|(x, y)| x.strict_eq(y))
98 }
99}
100
101#[derive(Clone, Debug, From, PartialEq, Eq, Serialize, Deserialize)]
104pub enum Element<'a> {
105 Block(BlockElement<'a>),
106 Inline(InlineElement<'a>),
107 InlineBlock(InlineBlockElement<'a>),
108}
109
110impl Element<'_> {
111 pub fn to_borrowed(&self) -> Element {
112 match self {
113 Self::Block(x) => Element::Block(x.to_borrowed()),
114 Self::Inline(x) => Element::Inline(x.to_borrowed()),
115 Self::InlineBlock(x) => Element::InlineBlock(x.to_borrowed()),
116 }
117 }
118
119 pub fn into_owned(self) -> Element<'static> {
120 match self {
121 Self::Block(x) => Element::Block(x.into_owned()),
122 Self::Inline(x) => Element::Inline(x.into_owned()),
123 Self::InlineBlock(x) => Element::InlineBlock(x.into_owned()),
124 }
125 }
126}
127
128impl<'a> IntoChildren for Element<'a> {
129 type Child = Located<Element<'a>>;
130
131 fn into_children(self) -> Vec<Self::Child> {
132 match self {
133 Self::Block(x) => x.into_children(),
134 Self::Inline(x) => x
135 .into_children()
136 .into_iter()
137 .map(|x| x.map(Element::from))
138 .collect(),
139 Self::InlineBlock(x) => x.into_children(),
140 }
141 }
142}
143
144impl<'a> StrictEq for Element<'a> {
145 fn strict_eq(&self, other: &Self) -> bool {
146 match (self, other) {
147 (Self::Block(x), Self::Block(y)) => x.strict_eq(y),
148 (Self::Inline(x), Self::Inline(y)) => x.strict_eq(y),
149 (Self::InlineBlock(x), Self::InlineBlock(y)) => x.strict_eq(y),
150 _ => false,
151 }
152 }
153}
154
155impl<'a> Element<'a> {
156 pub fn as_block_element(&self) -> Option<&BlockElement<'a>> {
157 match self {
158 Self::Block(ref x) => Some(x),
159 _ => None,
160 }
161 }
162
163 pub fn into_block_element(self) -> Option<BlockElement<'a>> {
164 match self {
165 Self::Block(x) => Some(x),
166 _ => None,
167 }
168 }
169
170 pub fn as_inline_element(&self) -> Option<&InlineElement<'a>> {
171 match self {
172 Self::Inline(ref x) => Some(x),
173 _ => None,
174 }
175 }
176
177 pub fn into_inline_element(self) -> Option<InlineElement<'a>> {
178 match self {
179 Self::Inline(x) => Some(x),
180 _ => None,
181 }
182 }
183
184 pub fn as_inline_block_element(&self) -> Option<&InlineBlockElement<'a>> {
185 match self {
186 Self::InlineBlock(ref x) => Some(x),
187 _ => None,
188 }
189 }
190
191 pub fn into_inline_block_element(self) -> Option<InlineBlockElement<'a>> {
192 match self {
193 Self::InlineBlock(x) => Some(x),
194 _ => None,
195 }
196 }
197}
198
199#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
202pub enum InlineBlockElement<'a> {
203 ListItem(ListItem<'a>),
204 Term(Term<'a>),
205 Definition(Definition<'a>),
206}
207
208impl<'a> From<ListItem<'a>> for InlineBlockElement<'a> {
209 fn from(list_item: ListItem<'a>) -> Self {
210 Self::ListItem(list_item)
211 }
212}
213
214impl InlineBlockElement<'_> {
215 pub fn to_borrowed(&self) -> InlineBlockElement {
216 match self {
217 Self::ListItem(x) => InlineBlockElement::ListItem(x.to_borrowed()),
218 Self::Term(x) => InlineBlockElement::Term(x.to_borrowed()),
219 Self::Definition(x) => {
220 InlineBlockElement::Definition(x.to_borrowed())
221 }
222 }
223 }
224
225 pub fn into_owned(self) -> InlineBlockElement<'static> {
226 match self {
227 Self::ListItem(x) => InlineBlockElement::ListItem(x.into_owned()),
228 Self::Term(x) => InlineBlockElement::Term(x.into_owned()),
229 Self::Definition(x) => {
230 InlineBlockElement::Definition(x.into_owned())
231 }
232 }
233 }
234}
235
236impl<'a> IntoChildren for InlineBlockElement<'a> {
237 type Child = Located<Element<'a>>;
238
239 fn into_children(self) -> Vec<Self::Child> {
240 match self {
241 Self::ListItem(x) => x.into_children(),
242 Self::Term(x) => x
243 .into_children()
244 .into_iter()
245 .map(|x| x.map(Element::from))
246 .collect(),
247 Self::Definition(x) => x
248 .into_children()
249 .into_iter()
250 .map(|x| x.map(Element::from))
251 .collect(),
252 }
253 }
254}
255
256impl<'a> StrictEq for InlineBlockElement<'a> {
257 fn strict_eq(&self, other: &Self) -> bool {
258 match (self, other) {
259 (Self::ListItem(x), Self::ListItem(y)) => x.strict_eq(y),
260 (Self::Term(x), Self::Term(y)) => x.strict_eq(y),
261 (Self::Definition(x), Self::Definition(y)) => x.strict_eq(y),
262 _ => false,
263 }
264 }
265}
266
267macro_rules! element_impl_from {
268 ($type:ty, $class:ident) => {
269 impl<'a> From<$type> for Element<'a> {
270 fn from(value: $type) -> Self {
271 Self::from($class::from(value))
272 }
273 }
274 };
275}
276
277element_impl_from!(Blockquote<'a>, BlockElement);
278element_impl_from!(DefinitionList<'a>, BlockElement);
279element_impl_from!(Divider, BlockElement);
280element_impl_from!(Header<'a>, BlockElement);
281element_impl_from!(List<'a>, BlockElement);
282element_impl_from!(MathBlock<'a>, BlockElement);
283element_impl_from!(Paragraph<'a>, BlockElement);
284element_impl_from!(Placeholder<'a>, BlockElement);
285element_impl_from!(CodeBlock<'a>, BlockElement);
286element_impl_from!(Table<'a>, BlockElement);
287
288element_impl_from!(Text<'a>, InlineElement);
289element_impl_from!(DecoratedText<'a>, InlineElement);
290element_impl_from!(Keyword, InlineElement);
291element_impl_from!(Link<'a>, InlineElement);
292element_impl_from!(Tags<'a>, InlineElement);
293element_impl_from!(CodeInline<'a>, InlineElement);
294element_impl_from!(MathInline<'a>, InlineElement);
295
296element_impl_from!(ListItem<'a>, InlineBlockElement);