rbatis_codegen/codegen/
loader_html.rs

1use html_parser::{Dom, Node, Result};
2use std::collections::HashMap;
3use std::fmt::{Debug, Display, Formatter};
4use crate::error::Error;
5
6#[derive(Clone, Eq, PartialEq, Debug)]
7pub struct Element {
8    pub tag: String,
9    pub data: String,
10    pub attrs: HashMap<String, String>,
11    pub childs: Vec<Element>,
12}
13
14impl Display for Element {
15    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
16        match self.tag.as_str() {
17            "" => {
18                f.write_str(&self.data)?;
19            }
20            _ => {
21                f.write_str("<")?;
22                f.write_str(&self.tag)?;
23                for (k, v) in &self.attrs {
24                    f.write_str(" ")?;
25                    f.write_str(k)?;
26                    f.write_str("=\"")?;
27                    f.write_str(v)?;
28                    f.write_str("\"")?;
29                }
30                f.write_str(">")?;
31                for x in &self.childs {
32                    std::fmt::Display::fmt(x, f)?;
33                }
34                //</if>
35                f.write_str("</")?;
36                f.write_str(&self.tag)?;
37                f.write_str(">")?;
38            }
39        }
40        return Ok(());
41    }
42}
43
44pub fn as_element(args: &Vec<Node>) -> Vec<Element> {
45    let mut els = vec![];
46    for x in args {
47        let mut el = Element {
48            tag: "".to_string(),
49            data: "".to_string(),
50            attrs: HashMap::with_capacity(50),
51            childs: vec![],
52        };
53        match x {
54            Node::Text(txt) => {
55                if txt.is_empty() {
56                    continue;
57                }
58                el.data = txt.to_string();
59            }
60            Node::Element(element) => {
61                el.tag = element.name.to_string();
62                if el.tag == "bk" {
63                    el.tag = "break".to_string();
64                }
65                if element.id.is_some() {
66                    el.attrs.insert(
67                        "id".to_string(),
68                        element.id.as_ref().unwrap_or(&String::new()).clone(),
69                    );
70                }
71                for (k, v) in &element.attributes {
72                    el.attrs
73                        .insert(k.clone(), v.as_ref().unwrap_or(&String::new()).clone());
74                }
75                if !element.children.is_empty() {
76                    let childs = as_element(&element.children);
77                    el.childs = childs;
78                }
79            }
80            Node::Comment(_comment) => {
81                // println!("comment:{}", comment);
82            }
83        }
84        els.push(el);
85    }
86    els
87}
88
89pub fn load_html(html: &str) -> Result<Vec<Element>> {
90    let mut html = html.to_string();
91    html = html
92        .replace("<break>", "<bk>")
93        .replace("<break/>", "<bk/>")
94        .replace("</break>", "</bk>");
95    let dom = Dom::parse(&html)?;
96    let els = as_element(&dom.children);
97    return Ok(els);
98}
99
100impl Element {
101    /// get all strings
102    pub fn child_strings(&self) -> Vec<&str> {
103        let mut elements = vec![];
104        for x in &self.childs {
105            if x.tag.eq("") {
106                elements.push(x.data.as_str());
107            }
108            let v = x.child_strings();
109            for x in v {
110                elements.push(x);
111            }
112        }
113        elements
114    }
115    /// get all strings
116    pub fn child_string_cup(&self) -> usize {
117        let mut u = 0;
118        for x in self.child_strings() {
119            u += x.len();
120        }
121        u
122    }
123}
124
125/// Loads HTML content into a vector of elements
126pub fn load_mapper_vec(html: &str) -> std::result::Result<Vec<Element>, Error> {
127    let elements = load_html(html).map_err(|e| Error::from(e.to_string()))?;
128
129    let mut mappers = Vec::new();
130    for element in elements {
131        if element.tag == "mapper" {
132            mappers.extend(element.childs);
133        } else {
134            mappers.push(element);
135        }
136    }
137
138    Ok(mappers)
139}