html-site-generator 0.0.1

Build a html file blazingly fast in Rust
Documentation
use std::io::Write;

use anyhow::Result;
use html_site_generator_macro::{add_attributes_field, DeriveSetHtmlAttributes};

use crate::attributes::{self, HtmlAttributes};
use crate::html::IntoHtmlNode;

#[derive(Debug, Clone, Default)]
pub enum ListType {
    Ordered,
    #[default]
    Unordered,
}

impl ListType {
    fn get_tags(&self) -> &str {
        match self {
            ListType::Ordered => "ol",
            ListType::Unordered => "ul",
        }
    }
}

#[add_attributes_field]
#[derive(Debug, DeriveSetHtmlAttributes)]
pub struct List {
    elements: Vec<(Box<dyn IntoHtmlNode>, HtmlAttributes)>,
    list_type: ListType,
}

impl List {
    pub fn new() -> Self {
        Self::new_with_ordering(ListType::default())
    }

    pub fn new_with_ordering(ordering: ListType) -> Self {
        List {
            elements: Vec::new(),
            list_type: ordering,
            _attributes: Default::default(),
        }
    }

    pub fn add_element(&mut self, item: impl IntoHtmlNode + 'static) {
        self.add_element_with_attributes(item, HtmlAttributes::default())
    }

    pub fn add_element_with_attributes(
        &mut self,
        item: impl IntoHtmlNode + 'static,
        attributes: HtmlAttributes,
    ) {
        self.elements.push((Box::new(item), attributes))
    }
}

impl IntoHtmlNode for List {
    fn transform_into_html_node(&self, buffer: &mut dyn Write) -> Result<()> {
        let symbol = self.list_type.get_tags();

        write!(buffer, "<{}", symbol)?;
        self._attributes.transform_into_html_node(buffer)?;
        writeln!(buffer, ">")?;

        for (element, attribute) in &self.elements {
            write!(buffer, "<li")?;
            attribute.transform_into_html_node(buffer)?;
            writeln!(buffer, ">")?;

            element.transform_into_html_node(buffer)?;

            writeln!(buffer, "</li>")?;
        }

        writeln!(buffer, "</{}>", symbol)?;

        Ok(())
    }
}