hxml/
lib.rs

1pub mod dom;
2mod err;
3mod gstring;
4mod node;
5mod predicate;
6mod parse;
7mod utils;
8
9#[cfg(test)]
10mod testbench;
11
12pub use err::HxmlError;
13pub use node::attribute::Attribute;
14pub use node::element::{Content, Element};
15pub use node::pointer::ElementPtr;
16pub use node::prolog::Prolog;
17
18use err::{reset_errors, read_errors};
19use gstring::set_global_string;
20use node::memory;
21use utils::into_v16;
22use parse::{get_prolog_end_index, parse_element, parse_prolog};
23use std::collections::HashMap;
24
25/// It's global.
26/// You can't handle multiple doms at once.
27/// It frees all the elements created before.
28pub fn into_dom(document: String) -> Result<(), HxmlError> {
29    memory::init();
30
31    unsafe {
32        dom::PROLOG = None;
33        dom::TAGS_BY_NAME = Some(HashMap::new());
34        dom::TAGS_BY_ID = Some(HashMap::new());
35        dom::TAGS_BY_CLASS = Some(HashMap::new());
36    }
37
38    let document = into_v16(&document);
39    set_global_string(document.clone());
40    reset_errors();
41
42    let mut curr_index = 0;
43
44    match get_prolog_end_index(&document, curr_index) {
45        Some(end_index) => {
46            unsafe {
47                dom::PROLOG = Some(parse_prolog(&document, curr_index).0);
48            }
49            curr_index = end_index + 1;
50        },
51        None => {}
52    }
53
54    match parse_element(&document, curr_index) {
55        Some((element, _)) => {
56            let result = element.to_real();
57            result.set_parent_recursive();
58            return Ok(());
59        },
60        None => {}
61    }
62
63    let errors = read_errors();
64
65    // reset global states
66    set_global_string(vec![]);
67    reset_errors();
68
69    if errors.len() > 0 {
70        return Err(errors[0].clone());
71    }
72
73    return Err(HxmlError::new(String::from("Unexpected Eof!"), usize::MAX));
74}
75
76#[cfg(test)]
77mod tests {
78    use std::fs::File;
79    use std::io::Read;
80    use crate::dom;
81
82    #[test]
83    fn file_test() {
84        let mut f = File::open("./tests/test1.html").unwrap();
85        let mut s = String::new();
86
87        f.read_to_string(&mut s).unwrap();
88
89        let lock = unsafe {
90            dom::LOCK.lock().unwrap()
91        };
92
93        crate::into_dom(s).unwrap();
94        dom::some_checks().unwrap();
95
96        drop(lock);
97    }
98
99}