1use sauron::{mt_dom::AttValue, prelude::*};
2use std::{fmt, fmt::Write};
3
4pub trait ToSyntax {
6 fn to_syntax(
8 &self,
9 buffer: &mut dyn Write,
10 use_macros: bool,
11 indent: usize,
12 ) -> fmt::Result;
13}
14
15impl<MSG: 'static> ToSyntax for Node<MSG> {
16 fn to_syntax(
17 &self,
18 buffer: &mut dyn Write,
19 use_macros: bool,
20 indent: usize,
21 ) -> fmt::Result {
22 match self {
23 Node::Text(text) => write!(buffer, "text(\"{}\")", text),
24 Node::Element(element) => {
25 element.to_syntax(buffer, use_macros, indent)
26 }
27 }
28 }
29}
30
31impl<MSG: 'static> ToSyntax for Attribute<MSG> {
32 fn to_syntax(
33 &self,
34 buffer: &mut dyn Write,
35 use_macros: bool,
36 indent: usize,
37 ) -> fmt::Result {
38 for att_value in self.value() {
39 match att_value {
40 AttValue::Plain(plain) => match plain {
41 AttributeValue::Simple(simple) => {
42 if let Some(_ns) = self.namespace() {
43 write!(
44 buffer,
45 "xlink_{}",
46 self.name().to_string(),
47 )?;
48 write!(buffer, "(")?;
49 simple.to_syntax(buffer, use_macros, indent)?;
50 write!(buffer, ")")?;
51 } else {
52 let matched_attribute_func =
53 sauron_parse::match_attribute_function(
54 &self.name(),
55 )
56 .is_some();
57 if matched_attribute_func {
58 write!(buffer, "{}", self.name().to_string(),)?;
59 write!(buffer, "(")?;
60 simple.to_syntax(buffer, use_macros, indent)?;
61 write!(buffer, ")")?;
62 } else {
63 write!(
64 buffer,
65 r#"attr("{}","#,
66 self.name().to_string(),
67 )?;
68 simple.to_syntax(buffer, use_macros, indent)?;
69 write!(buffer, ")")?;
70 }
71 }
72 }
73 AttributeValue::Style(styles_att) => {
74 write!(buffer, "style(\"")?;
75 for s_att in styles_att {
76 write!(buffer, "{};", s_att)?;
77 }
78 write!(buffer, "\")")?;
79 }
80 _ => (),
81 },
82 _ => (),
83 }
84 }
85 Ok(())
86 }
87}
88
89impl ToSyntax for Value {
90 fn to_syntax(
91 &self,
92 buffer: &mut dyn Write,
93 _use_macros: bool,
94 _indent: usize,
95 ) -> fmt::Result {
96 match self.as_str() {
97 Some(v_str) => {
98 if let Ok(v_str) = v_str.parse::<f64>() {
99 write!(buffer, "{}", v_str)?;
100 } else {
101 write!(buffer, "\"{}\"", v_str)?;
102 }
103 }
104 None => (),
105 }
106 Ok(())
107 }
108}
109
110impl<MSG: 'static> ToSyntax for Element<MSG> {
111 fn to_syntax(
112 &self,
113 buffer: &mut dyn Write,
114 use_macros: bool,
115 indent: usize,
116 ) -> fmt::Result {
117 if use_macros {
118 write!(buffer, "{}!(", self.tag())?;
119 } else {
120 write!(buffer, "{}(", self.tag())?;
121 }
122 if use_macros {
123 write!(buffer, "[")?;
124 } else {
125 write!(buffer, "vec![")?;
126 }
127 for attr in self.get_attributes().iter() {
128 attr.to_syntax(buffer, use_macros, indent)?;
129 write!(buffer, ",")?;
130 }
131 write!(buffer, "],")?;
132 if use_macros {
133 write!(buffer, "[")?;
134 } else {
135 write!(buffer, "vec![")?;
136 }
137 let children = self.get_children();
138 let first_child = children.get(0);
139 let is_first_child_text_node =
140 first_child.map(|node| node.is_text()).unwrap_or(false);
141
142 let is_lone_child_text_node =
143 children.len() == 1 && is_first_child_text_node;
144
145 if is_lone_child_text_node {
146 first_child.unwrap().to_syntax(buffer, use_macros, indent)?;
147 } else {
148 for child in self.get_children() {
150 write!(buffer, "\n{}", " ".repeat(indent + 1))?;
151 child.to_syntax(buffer, use_macros, indent + 1)?;
152 write!(buffer, ",")?;
153 }
154 }
155 if !is_lone_child_text_node && !children.is_empty() {
158 write!(buffer, "\n{}", " ".repeat(indent))?;
159 }
160 write!(buffer, "])")?;
161 Ok(())
162 }
163}