html_types/semantic/
body.rs

1use super::{
2    class::{Class, EmptyVector},
3    id::Id,
4    main::Main,
5    Script,
6};
7use crate::{
8    attributes::{Attribute, Value},
9    node::{Element, Node},
10    text::Text,
11};
12use std::convert::TryInto;
13
14pub struct Body {
15    pub content: Vec<BodyElement>,
16    pub scripts: Vec<Script>,
17    pub id: Option<Id>,
18    pub class: Vec<Class>,
19}
20
21pub enum BodyElement {
22    Text(Text),
23    Main(Main),
24}
25
26impl<'a> From<BodyElement> for Node<'a> {
27    fn from(value: BodyElement) -> Self {
28        match value {
29            BodyElement::Text(text) => text.into(),
30            BodyElement::Main(main) => main.into(),
31        }
32    }
33}
34
35impl<'a> From<Text> for BodyElement {
36    fn from(value: Text) -> Self {
37        BodyElement::Text(value)
38    }
39}
40
41impl<'a> From<Body> for Element<'a, Vec<Node<'a>>> {
42    fn from(value: Body) -> Self {
43        let empty: Vec<Node> = vec![];
44        let mut body: Element<Vec<Node>> = Element::body(empty);
45
46        match value.id {
47            Some(id) => body.set_attribute(Attribute::ID, id.into()),
48            None => (),
49        };
50
51        let class_value: Result<Value<'a>, EmptyVector> = value.class.try_into();
52        match class_value {
53            Ok(value) => body.set_attribute(Attribute::CLASS, value),
54            Err(_) => {}
55        }
56
57        for item in value.content {
58            let el: Node = item.into();
59            body.push(el);
60        }
61
62        for script in value.scripts {
63            let el: Node = script.into();
64            body.push(el);
65        }
66        body
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use crate::attributes::{Attribute, Value};
74
75    #[test]
76    fn preserves_id() {
77        let id = Id::create("abc").unwrap();
78        let id = Some(id);
79        let body = Body {
80            content: vec![],
81            scripts: vec![],
82            id,
83            class: vec![],
84        };
85        let el: Element<Vec<Node>> = body.into();
86        let result = el.has_attribute(&Attribute::ID);
87        assert!(result);
88    }
89
90    #[test]
91    fn preserves_class() {
92        let class = Class::create("abc").unwrap();
93        let body = Body {
94            content: vec![],
95            scripts: vec![],
96            id: None,
97            class: vec![class],
98        };
99        let el: Element<Vec<Node>> = body.into();
100        let result = el.get_attribute_value(&Attribute::CLASS);
101        let expected = {
102            let value = Value::owned("abc").unwrap();
103            &Some(value)
104        };
105        assert_eq!(result, expected);
106    }
107}