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}