hugr_cli/
mermaid.rs

1//! Render mermaid diagrams.
2use std::io::Write;
3
4use clap::Parser;
5use clap_verbosity_flag::log::Level;
6use clio::Output;
7use hugr::package::PackageValidationError;
8use hugr::HugrView;
9
10use crate::hugr_io::HugrInputArgs;
11use crate::OtherArgs;
12
13/// Dump the standard extensions.
14#[derive(Parser, Debug)]
15#[clap(version = "1.0", long_about = None)]
16#[clap(about = "Render mermaid diagrams..")]
17#[group(id = "hugr")]
18#[non_exhaustive]
19pub struct MermaidArgs {
20    /// Hugr input.
21    #[command(flatten)]
22    pub input_args: HugrInputArgs,
23
24    /// Validate package.
25    #[arg(
26        long,
27        help = "Validate before rendering, includes extension inference."
28    )]
29    pub validate: bool,
30    /// Output file '-' for stdout
31    #[clap(long, short, value_parser, default_value = "-")]
32    output: Output,
33
34    /// Additional arguments
35    #[command(flatten)]
36    pub other_args: OtherArgs,
37}
38
39impl MermaidArgs {
40    /// Write the mermaid diagram to the output.
41    pub fn run_print(&mut self) -> Result<(), crate::CliError> {
42        match self.input_args.hugr_json {
43            true => self.run_print_hugr(),
44            false => self.run_print_envelope(),
45        }
46    }
47
48    /// Write the mermaid diagram for a HUGR envelope.
49    pub fn run_print_envelope(&mut self) -> Result<(), crate::CliError> {
50        let package = self.input_args.get_package()?;
51
52        if self.validate {
53            package.validate()?;
54        }
55
56        for hugr in package.modules {
57            writeln!(self.output, "{}", hugr.mermaid_string())?;
58        }
59        Ok(())
60    }
61
62    /// Write the mermaid diagram for a legacy HUGR json.
63    pub fn run_print_hugr(&mut self) -> Result<(), crate::CliError> {
64        let hugr = self.input_args.get_hugr()?;
65
66        if self.validate {
67            hugr.validate()
68                .map_err(PackageValidationError::Validation)?;
69        }
70
71        writeln!(self.output, "{}", hugr.mermaid_string())?;
72        Ok(())
73    }
74
75    /// Test whether a `level` message should be output.
76    pub fn verbosity(&self, level: Level) -> bool {
77        self.other_args.verbosity(level)
78    }
79}