xml_paths/
xpath.rs

1use quick_xml::events::BytesEnd;
2use quick_xml::events::BytesStart;
3use std::fmt;
4
5pub fn start_tag_string(bytes_start: &BytesStart) -> Result<String, Box<dyn std::error::Error>> {
6    let tag = bytes_start.name();
7    let tag = tag.to_owned();
8    let tag = String::from_utf8(tag)?;
9    Ok(tag)
10}
11pub fn end_tag_string(bytes_end: &BytesEnd) -> Result<String, Box<dyn std::error::Error>> {
12    let tag = bytes_end.name();
13    let tag = tag.to_owned();
14    let tag = String::from_utf8(tag)?;
15    Ok(tag)
16}
17
18pub struct XPath(Vec<String>);
19
20impl XPath {
21    pub fn new() -> Self {
22        Self(vec!["".to_owned()])
23    }
24    pub fn push(&mut self, tag: String) {
25        self.0.push(tag);
26    }
27    pub fn pop(&mut self) -> Option<String> {
28        self.0.pop()
29    }
30    pub fn pop_checked(&mut self, tag: String) {
31        assert_eq!(self.pop().expect("can't end without starting."), tag);
32    }
33    pub fn as_string(&self) -> String {
34        let nodes = &self.0;
35        if nodes.len() == 1 {
36            "/".to_owned()
37        } else {
38            self.0.join("/")
39        }
40    }
41}
42
43impl Default for XPath {
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49impl fmt::Debug for XPath {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "{}", self.as_string())
52    }
53}
54
55impl fmt::Display for XPath {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(f, "{}", self.as_string())
58    }
59}