Skip to content

Commit 82ffecb

Browse files
authored
feat(cli): Add support for rendering to mermaid with vector graph command (#22787)
* Plumb in basic switch between output formats * Get rendering actually functional * flowchart appears to be preferred terminology over graph * comemnt about styling * add the new code after existing instead * Add changelog file * Replace expect with unwrap * Inline formatter arguments where possible * Remove code comment, it will move to PR body * link mermaid docs on format help
1 parent 3e13278 commit 82ffecb

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add support for rendering to Mermaid format in `vector graph`
2+
3+
authors: Firehed

src/graph.rs

+63
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ pub struct Opts {
4747
value_delimiter(',')
4848
)]
4949
pub config_dirs: Vec<PathBuf>,
50+
51+
/// Set the output format
52+
///
53+
/// See https://mermaid.js.org/syntax/flowchart.html#styling-and-classes for
54+
/// information on the `mermaid` format.
55+
#[arg(id = "format", long, default_value = "dot")]
56+
pub format: OutputFormat,
57+
}
58+
59+
#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
60+
pub enum OutputFormat {
61+
Dot,
62+
Mermaid,
5063
}
5164

5265
impl Opts {
@@ -96,6 +109,14 @@ pub(crate) fn cmd(opts: &Opts) -> exitcode::ExitCode {
96109
}
97110
};
98111

112+
let format = opts.format;
113+
match format {
114+
OutputFormat::Dot => render_dot(config),
115+
OutputFormat::Mermaid => render_mermaid(config),
116+
}
117+
}
118+
119+
fn render_dot(config: config::Config) -> exitcode::ExitCode {
99120
let mut dot = String::from("digraph {\n");
100121

101122
for (id, source) in config.sources() {
@@ -165,3 +186,45 @@ pub(crate) fn cmd(opts: &Opts) -> exitcode::ExitCode {
165186

166187
exitcode::OK
167188
}
189+
190+
fn render_mermaid(config: config::Config) -> exitcode::ExitCode {
191+
let mut mermaid = String::from("flowchart TD;\n");
192+
193+
writeln!(mermaid, "\n %% Sources").unwrap();
194+
for (id, _) in config.sources() {
195+
writeln!(mermaid, " {id}[/{id}/]").unwrap();
196+
}
197+
198+
writeln!(mermaid, "\n %% Transforms").unwrap();
199+
for (id, transform) in config.transforms() {
200+
writeln!(mermaid, " {id}{{{id}}}").unwrap();
201+
202+
for input in transform.inputs.iter() {
203+
if let Some(port) = &input.port {
204+
writeln!(mermaid, " {0} -->|{port}| {id}", input.component).unwrap();
205+
} else {
206+
writeln!(mermaid, " {0} --> {id}", input.component).unwrap();
207+
}
208+
}
209+
}
210+
211+
writeln!(mermaid, "\n %% Sinks").unwrap();
212+
for (id, sink) in config.sinks() {
213+
writeln!(mermaid, " {id}[\\{id}\\]").unwrap();
214+
215+
for input in &sink.inputs {
216+
if let Some(port) = &input.port {
217+
writeln!(mermaid, " {0} -->|{port}| {id}", input.component).unwrap();
218+
} else {
219+
writeln!(mermaid, " {0} --> {id}", input.component).unwrap();
220+
}
221+
}
222+
}
223+
224+
#[allow(clippy::print_stdout)]
225+
{
226+
println!("{}", mermaid);
227+
}
228+
229+
exitcode::OK
230+
}

0 commit comments

Comments
 (0)