1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use super::Node;
use crate::comment::Comment;
use crate::prelude::parse::{Error, Parsable, Parser};
use crate::text::Text;
use crate::{parse_attribute, parse_comment, parse_text};
use xmlparser::{StrSpan, Tokenizer};

#[derive(Debug)]
struct NodeParser<T>(Node<T>);

impl<T> NodeParser<T> {
    pub fn new(tag: String) -> Self {
        Self(Node::new(tag))
    }
}

impl<T> Parser for NodeParser<T>
where
    T: Parsable,
    T: From<Comment>,
    T: From<Text>,
{
    type Output = Node<T>;

    fn build(self) -> Result<Self::Output, Error> {
        Ok(self.0)
    }

    fn should_ignore_children(&self) -> bool {
        matches!(
            self.0.tag.as_str(),
            "area"
                | "base"
                | "br"
                | "col"
                | "embed"
                | "hr"
                | "img"
                | "input"
                | "link"
                | "meta"
                | "param"
                | "source"
                | "track"
                | "wbr"
        )
    }

    parse_attribute!();

    fn parse_child_element<'a>(
        &mut self,
        tag: xmlparser::StrSpan<'a>,
        tokenizer: &mut xmlparser::Tokenizer<'a>,
    ) -> Result<(), Error> {
        self.0.children.push(T::parse(tag, tokenizer)?);
        Ok(())
    }

    parse_comment!();
    parse_text!();
}

impl<T> Parsable for Node<T>
where
    T: Parsable,
    T: From<Comment>,
    T: From<Text>,
{
    fn parse<'a>(tag: StrSpan<'a>, tokenizer: &mut Tokenizer<'a>) -> Result<Self, Error> {
        NodeParser::<T>::new(tag.to_string())
            .parse(tokenizer)?
            .build()
    }
}