rbatis_codegen/codegen/
loader_html.rs1use crate::error::Error;
2use scraper::{Html, Node};
3use std::collections::HashMap;
4use std::fmt::{Display, Formatter};
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 f.write_str("</")?;
36 f.write_str(&self.tag)?;
37 f.write_str(">")?;
38 }
39 }
40 return Ok(());
41 }
42}
43
44fn collect_elements(el: scraper::ElementRef<'_>) -> Vec<Element> {
45 let mut els = vec![];
46 for node in el.children() {
47 match node.value() {
48 Node::Text(text) => {
49 let txt = text.to_string();
50 if txt.trim().is_empty() {
51 continue;
52 }
53 els.push(Element {
54 tag: String::new(),
55 data: txt,
56 attrs: HashMap::new(),
57 childs: vec![],
58 });
59 }
60 Node::Element(elem) => {
61 if let Some(child_ref) = scraper::ElementRef::wrap(node) {
62 let mut attrs = HashMap::new();
63 for (k, v) in elem.attrs() {
64 attrs.insert(k.to_string(), v.to_string());
65 }
66 els.push(Element {
67 tag: elem.name().to_string(),
68 data: String::new(),
69 attrs,
70 childs: collect_elements(child_ref),
71 });
72 }
73 }
74 Node::Comment(_) => {}
75 _ => {}
76 }
77 }
78 els
79}
80
81pub fn load_html(html: &str) -> std::result::Result<Vec<Element>, String> {
82 let document = Html::parse_fragment(html);
83 Ok(collect_elements(document.root_element()))
84}
85
86impl Element {
87 pub fn child_strings(&self) -> Vec<&str> {
89 let mut elements = vec![];
90 for x in &self.childs {
91 if x.tag.eq("") {
92 elements.push(x.data.as_str());
93 }
94 let v = x.child_strings();
95 for x in v {
96 elements.push(x);
97 }
98 }
99 elements
100 }
101 pub fn child_string_cup(&self) -> usize {
103 let mut u = 0;
104 for x in self.child_strings() {
105 u += x.len();
106 }
107 u
108 }
109}
110
111pub fn load_mapper_vec(html: &str) -> std::result::Result<Vec<Element>, Error> {
113 let elements = load_html(html).map_err(|e| Error::from(e))?;
114
115 let mut mappers = Vec::new();
116 for element in elements {
117 if element.tag == "mapper" {
118 mappers.extend(element.childs);
119 } else {
120 mappers.push(element);
121 }
122 }
123
124 Ok(mappers)
125}