xavier_internal/deserialize/
instructions.rs1use quick_xml::events::Event;
2use quick_xml::Reader;
3use crate::deserialize::error::PError;
4
5#[macro_export]
6macro_rules! instructions {
7 ($expr:expr, $tag:expr) => { xavier::deserialize::instructions::parse($expr, $tag) };
8}
9
10pub fn parse(xml: &str, function: fn(tag: String, instruction: String, params: String) -> ()) -> Result<(), PError> {
11 let mut reader = Reader::from_str(xml);
12 let mut stack: Vec<String> = vec![];
13 loop {
14 match reader.read_event() {
15 Err(error) => { return Err(PError::new(&format!("Error at position {}: {:?}", reader.buffer_position(), error))) },
16 Ok(Event::Eof) => { break },
17 Ok(Event::Start(event)) => {
18 for context in &stack {
19 if let Some(context) = pi_obj(&context) {
20 function(String::from_utf8(event.name().0.to_vec())?, context.0.to_string(), context.1.to_string());
21 }
22 }
23 stack.clear()
24 },
25 Ok(Event::End(_)) => {},
26 Ok(Event::Empty(_)) => {},
27 Ok(Event::Decl(_)) => {},
28 Ok(Event::PI(event)) => {
29 stack.push(String::from_utf8(event.to_vec())?);
30 }
31 Ok(Event::DocType(_)) => {},
32 Ok(Event::Text(_)) => {},
33 Ok(Event::Comment(_)) => {},
34 Ok(Event::CData(_)) => {},
35 };
36 };
37 Ok(())
38}
39
40fn pi_obj(input: &str) -> Option<(String, String)> {
41
42 let start_index = match input.find(' ') {
43 Some(idx) => idx,
44 None => {
45 return None;
46 }
47 };
48 let name = &input[0..start_index];
49 let params = &input[start_index + 1..input.len()];
50 Some((name.to_string(), params.to_string()))
51}
52
53
54