daab/diagnostics/
visgraph.rs1
2
3use super::CanBase;
4use super::Doctor;
5use super::BuilderHandle;
6use super::ArtifactHandle;
7
8use std::io::Write;
9
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq)]
29pub struct VisgraphDocOptions {
30 pub show_builder_values: bool,
34
35 pub show_artifact_values: bool,
38}
39
40impl Default for VisgraphDocOptions {
41 fn default() -> Self {
42 VisgraphDocOptions {
43 show_builder_values: false,
44 show_artifact_values: true,
45 }
46 }
47}
48
49pub struct VisgraphDoc<W: Write> {
95 opts: VisgraphDocOptions,
97
98 output: Option<W>,
100
101 count: (u64, u64),
106}
107
108impl<W: Write> VisgraphDoc<W> {
109 pub fn new(opts: VisgraphDocOptions,
112 mut output: W) -> Self {
113
114 writeln!(output, "strict digraph {{ graph [labeljust = l];").unwrap();
115
116 VisgraphDoc {
117 opts,
118 output: Some(output),
119 count: (0, 0),
120 }
121 }
122
123 fn builder_str<'a, BCan>(&self, builder: &'a BuilderHandle<BCan>) -> &'a str {
125 if self.opts.show_builder_values {
126 &builder.dbg_text
127 } else {
128 builder.type_name
129 }
130 }
131
132 fn output(&mut self) -> &mut W {
133 self.output.as_mut().unwrap()
134 }
135
136 fn finish(&mut self) {
137 writeln!(self.output(), "}}").unwrap();
138 }
139
140 pub fn into_inner(mut self) -> W {
143 self.finish();
144 self.output.take().unwrap()
145 }
146}
147
148impl<W: Write> Drop for VisgraphDoc<W> {
149 fn drop(&mut self) {
150 if self.output.is_some() {
151 self.finish();
152 }
153 }
154}
155
156impl<ArtCan: CanBase, BCan, W: Write> Doctor<ArtCan, BCan> for VisgraphDoc<W> {
157 fn resolve(&mut self, builder: &BuilderHandle<BCan>, used: &BuilderHandle<BCan>) {
158
159 let s = self.builder_str(builder);
160 writeln!(self.output(),
161 r#" "{:p}" [label = {:?}]"#,
162 builder.id(),
163 s
164 ).unwrap();
165
166 let s = self.builder_str(used);
167 writeln!(self.output(),
168 r#" "{:p}" [label = {:?}]"#,
169 used.id(),
170 s
171 ).unwrap();
172
173 writeln!(self.output(),
174 r#" "{:p}" -> "{:p}""#,
175 builder.id(),
176 used.id()
177 ).unwrap();
178
179 self.output().flush().unwrap();
180
181 }
182
183
184 fn build(&mut self, builder: &BuilderHandle<BCan>, artifact: &ArtifactHandle<ArtCan>) {
185 let count = self.count;
186
187 let s = self.builder_str(builder);
188 writeln!(self.output(),
189 r#" "{:p}" [label = {:?}]"#,
190 builder.id(),
191 s
192 ).unwrap();
193
194 let s = if self.opts.show_artifact_values {
195 format!(" :\n{}", artifact.dbg_text)
196 } else {
197 "".into()
198 };
199
200 writeln!(self.output(),
201 r##" "{0}.{1}-{2:p}" [label = "#{0}.{1} {3}{4}", shape = box]"##,
202 count.0,
203 count.1,
204 artifact.value.can_as_ptr(),
205 artifact.type_name,
206 s
207 ).unwrap();
208
209 writeln!(self.output(),
210 r#" "{:p}" -> "{}.{}-{:p}" [arrowhead = "none"]"#,
211 builder.id(),
212 count.0,
213 count.1,
214 artifact.value.can_as_ptr()
215 ).unwrap();
216
217 self.output().flush().unwrap();
218
219
220 self.count.1 += 1;
221
222 }
223
224 fn clear(&mut self) {
225 self.count.0 += 1;
227 self.count.1 = 0;
228 }
229
230 fn invalidate(&mut self, _builder: &BuilderHandle<BCan>) {
231 self.count.0 += 1;
233 self.count.1 = 0;
234 }
235}
236
237
238