-
Notifications
You must be signed in to change notification settings - Fork 0
/
dom.rs
71 lines (68 loc) · 2.29 KB
/
dom.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::collections::HashMap;
#[derive(Debug)]
pub struct Element{
pub tag: String,
pub attributes: HashMap<String, String>,
pub children: Vec<Element>
}
pub fn parse_html(html: &str) -> Element {
let mut root = Element {
tag: String::new(),
attributes: HashMap::new(),
children: Vec::new(),
};
let mut current_element = &mut root;
let mut in_tag = false;
let mut tag_name = String::new();
let mut attribute_name = String::new();
let mut attribute_value = String::new();
let mut escape_next = false;
for character in html.chars(){
match character {
'>' if in_tag => {
in_tag = false;
current_element.tag = tag_name;
tag_name = String::new();
if !attribute_name.is_empty() {
current_element
.attributes
.insert(attribute_name, attribute_value);
attribute_name = String::new();
attribute_value = String::new();
}
}
' ' | '/' if in_tag => {
current_element.tag = tag_name;
tag_name = String::new();
if !attribute_name.is_empty() {
current_element
.attributes
.insert(attribute_name, attribute_value);
attribute_name = String::new();
attribute_value = String::new();
}
}
'\'' | '"' if in_tag => { escape_next = true }
'=' if in_tag => {
attribute_value = String::new();
}
_ if in_tag => {
if attribute_name.is_empty() {
tag_name.push(character);
} else if !escape_next {
attribute_value.push(character);
} else {
escape_next = false;
attribute_value.push(character);
}
}
'<' => in_tag = true,
_ => current_element.children.push(Element {
tag: character.to_string(),
attributes: HashMap::new(),
children: Vec::new(),
}),
}
}
root
}