parco_xml/dexml/
append_path.rs

1use crate::de::Reader;
2
3/// used to control the `path` parameter in error handling
4///
5/// you should use [`Reader::append_path`] and [`Reader::exit_path`] to
6/// control "where" you are in the xml tree so if you encounter an error
7/// you can give a helpful message to the user
8pub enum AppendPath<'a> {
9    /// text node shown in the path as "\:text"
10    Text,
11    /// attribute shown in the path as "\:attr"
12    GeneralAttr,
13    /// attribute shown in the path as "\:\[attr_name\]" where the name is [str] you provide
14    NamedAttr(&'a str),
15    /// element shown in the path as "\/\[element_name\]" where the name is [str] you provide
16    Element(&'a str),
17    /// custom path show as "\:\[name\]" where the name is [str] you provide
18    Custom(&'a str),
19}
20
21impl<'a> Reader<'a> {
22    /// used to control the `path` parameter in error handling
23    ///
24    /// you should use [`Reader::append_path`] and [`Reader::exit_path`] to
25    /// control "where" you are in the xml tree so if you encounter an error
26    /// you can give a helpful message to the user
27    pub fn append_path(&mut self, append_path: AppendPath) {
28        let (ch, n) = match append_path {
29            AppendPath::Text => (':', "text"),
30            AppendPath::GeneralAttr => (':', "attr"),
31            AppendPath::NamedAttr(attr) => (':', attr),
32            AppendPath::Element(el) => ('/', el),
33            AppendPath::Custom(el) => (':', el),
34        };
35        self.path.push(ch);
36        self.path.push_str(n);
37    }
38
39    /// remove the last part of the path until ":" or "/" for example
40    ///
41    /// if the path was "/document/element:my_attr"
42    /// and [`Reader::exit_path`] is called
43    /// then the result is "/document/element"
44    ///
45    /// ```rust,ignore
46    /// reader.append_path(AppendPath::Element("document"));
47    /// reader.append_path(AppendPath::Element("element"));
48    /// reader.append_path(AppendPath::NamedAttr("my_attr"));
49    /// assert_eq!(reader.path(), "/document/element:my_attr");
50    ///
51    /// reader.exit_path();
52    /// assert_eq!(reader.path(), "/document/element");
53    ///
54    /// ```
55    ///
56    pub fn exit_path(&mut self) {
57        while let Some(ch) = self.path.pop() {
58            if matches!(ch, '/' | ':') {
59                return;
60            }
61        }
62    }
63}