use std::{convert::Infallible, fmt::Write};
use super::kind_name;
use crate::{Cursor, Flow, Pattern, Visitor, visit};
impl Pattern {
#[must_use]
pub fn to_dot(&self) -> String {
match visit(self, Dot::default()) {
Ok(output) => output,
Err(error) => match error {},
}
}
}
struct Dot {
output: String,
}
impl Default for Dot {
fn default() -> Self {
Self {
output: String::from("digraph ast {\n node [shape=box];\n"),
}
}
}
impl Visitor for Dot {
type Output = String;
type Err = Infallible;
fn enter(&mut self, node: Cursor<'_>) -> Result<Flow, Self::Err> {
let label = format!("{}\\n{}", kind_name(node.kind()), escape_dot(node.text()));
writeln!(self.output, " n{} [label=\"{}\"];", node.id().0, label)
.expect("writing to String cannot fail");
for child in node.children() {
writeln!(self.output, " n{} -> n{};", node.id().0, child.id().0)
.expect("writing to String cannot fail");
}
Ok(Flow::Continue)
}
fn finish(mut self) -> Result<Self::Output, Self::Err> {
self.output.push_str("}\n");
Ok(self.output)
}
}
fn escape_dot(text: &str) -> String {
text.replace('\\', "\\\\")
.replace('"', "\\\"")
.replace('\n', "\\n")
}