html_site_generator/html/
list.rs1use std::io::Write;
2
3use anyhow::Result;
4use html_site_generator_macro::{add_attributes_field, DeriveSetHtmlAttributes};
5
6use crate::attributes::{self, HtmlAttributes};
7use crate::html::IntoHtmlNode;
8
9#[derive(Debug, Clone, Default)]
10pub enum ListType {
11 Ordered,
12 #[default]
13 Unordered,
14}
15
16impl ListType {
17 fn get_tags(&self) -> &str {
18 match self {
19 ListType::Ordered => "ol",
20 ListType::Unordered => "ul",
21 }
22 }
23}
24
25#[add_attributes_field]
26#[derive(Debug, DeriveSetHtmlAttributes)]
27pub struct List {
28 elements: Vec<(Box<dyn IntoHtmlNode>, HtmlAttributes)>,
29 list_type: ListType,
30}
31
32impl List {
33 pub fn new() -> Self {
34 Self::new_with_ordering(ListType::default())
35 }
36
37 pub fn new_with_ordering(ordering: ListType) -> Self {
38 List {
39 elements: Vec::new(),
40 list_type: ordering,
41 _attributes: Default::default(),
42 }
43 }
44
45 pub fn add_element(&mut self, item: impl IntoHtmlNode + 'static) {
46 self.add_element_with_attributes(item, HtmlAttributes::default())
47 }
48
49 pub fn add_element_with_attributes(
50 &mut self,
51 item: impl IntoHtmlNode + 'static,
52 attributes: HtmlAttributes,
53 ) {
54 self.elements.push((Box::new(item), attributes))
55 }
56}
57
58impl IntoHtmlNode for List {
59 fn transform_into_html_node(&self, buffer: &mut dyn Write) -> Result<()> {
60 let symbol = self.list_type.get_tags();
61
62 write!(buffer, "<{}", symbol)?;
63 self._attributes.transform_into_html_node(buffer)?;
64 writeln!(buffer, ">")?;
65
66 for (element, attribute) in &self.elements {
67 write!(buffer, "<li")?;
68 attribute.transform_into_html_node(buffer)?;
69 writeln!(buffer, ">")?;
70
71 element.transform_into_html_node(buffer)?;
72
73 writeln!(buffer, "</li>")?;
74 }
75
76 writeln!(buffer, "</{}>", symbol)?;
77
78 Ok(())
79 }
80}