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}