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::HugrView;
8use hugr::package::PackageValidationError;
9
10use crate::OtherArgs;
11use crate::hugr_io::HugrInputArgs;
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        if self.input_args.hugr_json {
43            self.run_print_hugr()
44        } else {
45            self.run_print_envelope()
46        }
47    }
48
49    /// Write the mermaid diagram for a HUGR envelope.
50    pub fn run_print_envelope(&mut self) -> Result<(), crate::CliError> {
51        let package = self.input_args.get_package()?;
52
53        if self.validate {
54            package.validate()?;
55        }
56
57        for hugr in package.modules {
58            writeln!(self.output, "{}", hugr.mermaid_string())?;
59        }
60        Ok(())
61    }
62
63    /// Write the mermaid diagram for a legacy HUGR json.
64    pub fn run_print_hugr(&mut self) -> Result<(), crate::CliError> {
65        let hugr = self.input_args.get_hugr()?;
66
67        if self.validate {
68            hugr.validate()
69                .map_err(PackageValidationError::Validation)?;
70        }
71
72        writeln!(self.output, "{}", hugr.mermaid_string())?;
73        Ok(())
74    }
75
76    /// Test whether a `level` message should be output.
77    #[must_use]
78    pub fn verbosity(&self, level: Level) -> bool {
79        self.other_args.verbosity(level)
80    }
81}