1use crate::{
2 DeXmlError,
3 dexml::{
4 lex::{Colon, Ident, OpenAngle, Slash},
5 parse::Action,
6 reader::Reader,
7 },
8};
9
10pub struct Tag<'a>(pub &'a str);
11
12pub enum PeekedTag<'a> {
14 Open(&'a str),
16 Close(&'a str),
18}
19
20impl<'a> Reader<'a> {
21 pub(crate) fn parse_tag(&mut self, action: Action) -> Result<Tag<'a>, DeXmlError> {
22 let ident: Ident = self.parse(action)?;
23
24 match self.lexer.peek(':') {
25 true => {
26 self.parse::<Colon>(action)?;
27 let ident: Ident = self.parse(action)?;
28 Ok(Tag(ident.0))
29 }
30 false => Ok(Tag(ident.0)),
31 }
32 }
33
34 pub fn peek_tag(&mut self) -> Option<&'a str> {
36 let mut lexer = self.lexer.clone();
37
38 lexer.token::<OpenAngle>().ok()?;
39
40 let ident = lexer.token::<Ident>().ok()?;
41 if lexer.peek(':') {
42 lexer.token::<Colon>().ok()?;
43 let id = lexer.token::<Ident>().ok()?;
44 return Some(id.0);
45 }
46
47 Some(ident.0)
48 }
49
50 pub fn peek_closing_tag(&mut self) -> Option<&'a str> {
52 let mut lexer = self.lexer.clone();
53
54 lexer.token::<OpenAngle>().ok()?;
55 lexer.token::<Slash>().ok()?;
56
57 let ident = lexer.token::<Ident>().ok()?;
58 if lexer.peek(':') {
59 lexer.token::<Colon>().ok()?;
60 let id = lexer.token::<Ident>().ok()?;
61 return Some(id.0);
62 }
63
64 Some(ident.0)
65 }
66
67 pub fn peek_open_or_closing_tag(&mut self) -> Option<PeekedTag<'a>> {
69 let mut lexer = self.lexer.clone();
70
71 lexer.token::<OpenAngle>().ok()?;
72 let is_close = match lexer.peek('/') {
73 true => {
74 lexer.token::<Slash>().ok()?;
75 true
76 }
77 false => false,
78 };
79
80 let ident = lexer.token::<Ident>().ok()?;
81 let tag = match lexer.peek(':') {
82 true => {
83 lexer.token::<Colon>().ok()?;
84 let id = lexer.token::<Ident>().ok()?;
85 id.0
86 }
87 false => ident.0,
88 };
89
90 match is_close {
91 true => Some(PeekedTag::Close(tag)),
92 false => Some(PeekedTag::Open(tag)),
93 }
94 }
95}