xavier_internal/deserialize/
doctype.rs1use quick_xml::events::Event;
2use quick_xml::Reader;
3use crate::deserialize::error::PError;
4
5#[macro_export]
6macro_rules! doctype {
7 ($expr:expr) => { xavier::deserialize::doctype::parse($expr) };
8}
9
10pub fn parse(xml: &str) -> Result<(String, String), PError> {
11 let mut reader = Reader::from_str(xml);
12 loop {
13 match reader.read_event() {
14 Err(error) => { return Err(PError::new(&format!("Error at position {}: {:?}", reader.buffer_position(), error))) },
15 Ok(Event::Eof) => { break },
16 Ok(Event::Start(_)) => { break },
17 Ok(Event::End(_)) => {},
18 Ok(Event::Empty(_)) => {},
19 Ok(Event::Decl(_)) => {},
20 Ok(Event::PI(_)) => {},
21 Ok(Event::DocType(event)) => {
22 let doc_type = String::from_utf8(event.to_vec())?;
23 return if let Some((name, file)) = doctype_obj(&doc_type) {
24 Ok((name, file))
25 } else {
26 Err(PError::new("Unsupported content"))
27 }
28 },
29 Ok(Event::Text(_)) => {},
30 Ok(Event::Comment(_)) => {},
31 Ok(Event::CData(_)) => {},
32 };
33 };
34 Err(PError::new("Doctype not found!"))
35}
36
37fn doctype_obj(input: &str) -> Option<(String, String)> {
38
39 let parts: Vec<&str> = input.trim().split_whitespace().collect();
40
41 if parts.is_empty() { return None; }
42
43 let tag_name = parts[0].to_string();
44 let file = parts.iter().find(|&&part| part.starts_with("\""));
45
46 match file {
47 Some(file) => {
48 let file = file.trim_start_matches('"').trim_end_matches('"');
49 Some((tag_name, file.to_string()))
50 }
51 None => None,
52 }
53}