lib.rs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. use dioxus_rsx::{BodyNode, CallBody, Element, ElementAttr, ElementAttrNamed, IfmtInput};
  2. pub use html_parser::{Dom, Node};
  3. use proc_macro2::{Ident, Span};
  4. use syn::LitStr;
  5. pub fn convert_from_html(dom: Dom) -> CallBody {
  6. CallBody {
  7. roots: dom
  8. .children
  9. .into_iter()
  10. .map(|f| create_body_node_from_node(f))
  11. .filter_map(|f| f)
  12. .collect(),
  13. }
  14. }
  15. fn create_body_node_from_node(node: Node) -> Option<BodyNode> {
  16. match node {
  17. Node::Text(text) => Some(BodyNode::Text(ifmt_from_text(text))),
  18. Node::Element(el) => {
  19. use convert_case::{Case, Casing};
  20. let el_name = el.name.to_case(Case::Snake);
  21. let el_name = Ident::new(el_name.as_str(), Span::call_site());
  22. let mut attributes: Vec<_> = el
  23. .attributes
  24. .into_iter()
  25. .map(|(name, value)| {
  26. let ident = if matches!(name.as_str(), "for" | "async" | "type" | "as") {
  27. Ident::new_raw(name.as_str(), Span::call_site())
  28. } else {
  29. let new_name = name.to_case(Case::Snake);
  30. Ident::new(new_name.as_str(), Span::call_site())
  31. };
  32. ElementAttrNamed {
  33. attr: ElementAttr::AttrText {
  34. name: ident,
  35. value: ifmt_from_text(value.unwrap_or("false".to_string())),
  36. },
  37. el_name: el_name.clone(),
  38. }
  39. })
  40. .collect();
  41. let class = el.classes.join(" ");
  42. if !class.is_empty() {
  43. attributes.push(ElementAttrNamed {
  44. attr: ElementAttr::AttrText {
  45. name: Ident::new("class", Span::call_site()),
  46. value: ifmt_from_text(class),
  47. },
  48. el_name: el_name.clone(),
  49. });
  50. }
  51. if let Some(id) = el.id {
  52. attributes.push(ElementAttrNamed {
  53. attr: ElementAttr::AttrText {
  54. name: Ident::new("id", Span::call_site()),
  55. value: ifmt_from_text(id),
  56. },
  57. el_name: el_name.clone(),
  58. });
  59. }
  60. let children = el
  61. .children
  62. .into_iter()
  63. .map(|f| create_body_node_from_node(f))
  64. .filter_map(|f| f)
  65. .collect();
  66. Some(BodyNode::Element(Element {
  67. name: el_name,
  68. children,
  69. attributes,
  70. _is_static: false,
  71. key: None,
  72. }))
  73. }
  74. Node::Comment(_) => None,
  75. }
  76. }
  77. fn ifmt_from_text(text: String) -> IfmtInput {
  78. IfmtInput {
  79. source: Some(LitStr::new(text.as_str(), Span::call_site())),
  80. segments: vec![],
  81. }
  82. }