1mod document;
2mod dom_node;
3mod html;
4
5use std::{collections::VecDeque, iter};
6
7pub use document::*;
8pub use dom_node::*;
9use html::*;
10pub use html::{parse_html, parse_html_from_string, Html};
11
12#[derive(Debug, PartialEq)]
14pub struct IterableNodes(pub Vec<DomNode>);
15
16impl From<String> for IterableNodes {
17 fn from(value: String) -> Self {
18 Self(vec![DomNode::create_text(value)])
19 }
20}
21impl From<&String> for IterableNodes {
22 fn from(value: &String) -> Self {
23 Self(vec![DomNode::create_text(value)])
24 }
25}
26
27impl From<&str> for IterableNodes {
28 fn from(value: &str) -> Self {
29 Self(vec![DomNode::create_text(value)])
30 }
31}
32
33impl From<DomNode> for IterableNodes {
34 fn from(value: DomNode) -> Self {
35 Self(vec![value])
36 }
37}
38
39impl From<Vec<DomNode>> for IterableNodes {
40 fn from(value: Vec<DomNode>) -> Self {
41 Self(value)
42 }
43}
44
45impl FromIterator<DomNode> for IterableNodes {
46 fn from_iter<T: IntoIterator<Item = DomNode>>(iter: T) -> Self {
47 Self(iter.into_iter().collect())
48 }
49}
50
51impl FromIterator<Html> for IterableNodes {
52 fn from_iter<T: IntoIterator<Item = Html>>(iter: T) -> Self {
53 iter.into_iter()
54 .map(|value| match value {
55 Html::Comment { .. } => panic!("root html can't be comment"),
56 Html::Text { text } => DomNode::create_text(text),
57 Html::Element {
58 tag,
59 attributes,
60 children,
61 } => {
62 let root = DomNode::create_element_with_attributes(tag, attributes);
63 let mut queue: VecDeque<(Html, DomNode)> = VecDeque::from(
64 children
65 .into_iter()
66 .zip(std::iter::repeat(root.clone()))
67 .collect::<Vec<(Html, DomNode)>>(),
68 );
69 while let Some((c, parent)) = queue.pop_front() {
70 if let Some(p) = match c {
71 Html::Text { text } => Some(DomNode::create_text(text)),
72 Html::Element {
73 tag,
74 attributes,
75 children,
76 } => {
77 let p = DomNode::create_element_with_attributes(tag, attributes);
78 queue
79 .extend(children.into_iter().zip(std::iter::repeat(p.clone())));
80 Some(p)
81 }
82 _ => None,
83 } {
84 parent.append_child(p)
85 }
86 }
87 root
88 }
89 })
90 .collect()
91 }
92}
93
94impl From<Vec<Html>> for IterableNodes {
95 fn from(value: Vec<Html>) -> Self {
96 value.into_iter().collect()
97 }
98}
99
100impl From<Html> for IterableNodes {
101 fn from(value: Html) -> Self {
102 iter::once(value).collect()
103 }
104}