ftml/tree/list.rs
1/*
2 * tree/list.rs
3 *
4 * ftml - Library to parse Wikidot text
5 * Copyright (C) 2019-2025 Wikijump Team
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21use super::Element;
22use super::attribute::AttributeMap;
23use super::clone::elements_to_owned;
24use strum_macros::IntoStaticStr;
25
26#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
27#[serde(rename_all = "kebab-case", tag = "item-type")]
28pub enum ListItem<'t> {
29 /// This item is a series of elements.
30 ///
31 /// It's just an item in the list, which may have multiple elements
32 /// similar to any other container.
33 Elements {
34 attributes: AttributeMap<'t>,
35 elements: Vec<Element<'t>>,
36 },
37
38 /// This item in the list is a sub-list.
39 ///
40 /// That is, it's another, deeper list within the list.
41 SubList {
42 #[serde(flatten)]
43 element: Box<Element<'t>>,
44 },
45}
46
47impl ListItem<'_> {
48 pub fn to_owned(&self) -> ListItem<'static> {
49 match self {
50 ListItem::Elements {
51 attributes,
52 elements,
53 } => ListItem::Elements {
54 attributes: attributes.to_owned(),
55 elements: elements_to_owned(elements),
56 },
57 ListItem::SubList { element } => {
58 let element: &Element = element;
59
60 ListItem::SubList {
61 element: Box::new(element.to_owned()),
62 }
63 }
64 }
65 }
66}
67
68#[derive(
69 Serialize, Deserialize, IntoStaticStr, Debug, Copy, Clone, Hash, PartialEq, Eq,
70)]
71#[serde(rename_all = "kebab-case")]
72pub enum ListType {
73 /// Bullet lists, or "unordered lists" in HTML.
74 ///
75 /// Corresponds to the tag `<ul>`.
76 Bullet,
77
78 /// Numbered lists, or "ordered lists" in HTML.
79 ///
80 /// Corresponds to the tag `<ol>`.
81 Numbered,
82
83 /// Generic list, which does not have a preferred list type.
84 ///
85 /// This can be implemented in HTML with either
86 /// `<ul>` or `<ol>`, as these should not have any
87 /// list items that are not sub-lists.
88 Generic,
89}
90
91impl ListType {
92 #[inline]
93 pub fn name(self) -> &'static str {
94 self.into()
95 }
96
97 #[inline]
98 pub fn html_tag(self) -> &'static str {
99 match self {
100 ListType::Bullet | ListType::Generic => "ul",
101 ListType::Numbered => "ol",
102 }
103 }
104}