cercis_html/
element.rs

1use smallvec::SmallVec;
2use std::borrow::Cow;
3
4use crate::prelude::*;
5
6const CHLD_DEFAULT: usize = 8;
7const ATTR_DEFAULT: usize = 4;
8
9pub struct VElement<'a, const CHLD: usize = CHLD_DEFAULT, const ATTR: usize = ATTR_DEFAULT> {
10    name: Cow<'a, str>,
11    attrs: SmallVec<[VAttribute<'a>; ATTR]>,
12    children: SmallVec<[Box<dyn Render + 'a>; CHLD]>,
13    is_single: Option<bool>,
14}
15
16impl<'a> VElement<'a> {
17    pub fn new(name: impl Into<Cow<'a, str>>) -> Self {
18        Self {
19            name: name.into(),
20            attrs: SmallVec::new(),
21            children: SmallVec::new(),
22            is_single: None,
23        }
24    }
25
26    pub fn new_sized<const C: usize, const A: usize>(
27        name: impl Into<Cow<'a, str>>,
28    ) -> VElement<'a, C, A> {
29        VElement {
30            name: name.into(),
31            attrs: SmallVec::new(),
32            children: SmallVec::new(),
33            is_single: None,
34        }
35    }
36}
37
38impl<'a, const CHLD: usize, const ATTR: usize> VElement<'a, CHLD, ATTR> {
39    pub fn child(mut self, child: impl Render + 'a) -> Self {
40        self.children.push(Box::new(child));
41
42        self
43    }
44
45    pub fn attr(mut self, attr: impl Into<VAttribute<'a>>) -> Self {
46        self.attrs.push(attr.into());
47
48        self
49    }
50
51    pub fn single(mut self, value: bool) -> Self {
52        self.is_single = Some(value);
53
54        self
55    }
56
57    pub fn get_children_presize(&self) -> usize {
58        CHLD
59    }
60
61    pub fn get_attributes_presize(&self) -> usize {
62        ATTR
63    }
64
65    pub fn is_children_spilled(&self) -> bool {
66        self.children.spilled()
67    }
68
69    pub fn is_attributes_spilled(&self) -> bool {
70        self.attrs.spilled()
71    }
72}
73
74impl<const CHLD: usize, const ATTR: usize> Render for VElement<'_, CHLD, ATTR> {
75    fn render(&self) -> String {
76        let mut attrs = String::new();
77        let mut children = String::new();
78
79        for attr in self.attrs.iter() {
80            attrs.push_str(&attr.render())
81        }
82
83        for child in self.children.iter() {
84            children.push_str(&child.render())
85        }
86
87        match self.is_single {
88            Some(true) => format!("<{0}{1}>", self.name, attrs),
89            _ => format!("<{0}{1}>{2}</{0}>", self.name, attrs, children),
90        }
91    }
92}