hugr_cli/
lib.rs

1//! Standard command line tools, used by the hugr binary.
2
3use clap::{crate_version, Parser};
4use clap_verbosity_flag::log::Level;
5use clap_verbosity_flag::{InfoLevel, Verbosity};
6use hugr::envelope::EnvelopeError;
7use hugr::hugr::LoadHugrError;
8use hugr::package::{PackageEncodingError, PackageValidationError};
9use std::ffi::OsString;
10
11pub mod extensions;
12pub mod hugr_io;
13pub mod mermaid;
14pub mod validate;
15
16/// CLI arguments.
17#[derive(Parser, Debug)]
18#[clap(version = crate_version!(), long_about = None)]
19#[clap(about = "HUGR CLI tools.")]
20#[group(id = "hugr")]
21#[non_exhaustive]
22pub enum CliArgs {
23    /// Validate and visualize a HUGR file.
24    Validate(validate::ValArgs),
25    /// Write standard extensions out in serialized form.
26    GenExtensions(extensions::ExtArgs),
27    /// Write HUGR as mermaid diagrams.
28    Mermaid(mermaid::MermaidArgs),
29    /// External commands
30    #[command(external_subcommand)]
31    External(Vec<OsString>),
32}
33
34/// Error type for the CLI.
35#[derive(Debug, derive_more::Display, derive_more::Error, derive_more::From)]
36#[non_exhaustive]
37pub enum CliError {
38    /// Error reading input.
39    #[display("Error reading from path: {_0}")]
40    InputFile(std::io::Error),
41    /// Error parsing input.
42    #[display("Error parsing package: {_0}")]
43    Parse(serde_json::Error),
44    /// Package load error.
45    #[display("Error parsing package: {_0}")]
46    PackageLoad(PackageEncodingError),
47    /// Hugr load error.
48    #[display("Error loading hugr: {_0}")]
49    HugrLoad(LoadHugrError),
50    #[display("Error validating HUGR: {_0}")]
51    /// Errors produced by the `validate` subcommand.
52    Validate(PackageValidationError),
53    #[display("Error decoding HUGR envelope: {_0}")]
54    /// Errors produced by the `validate` subcommand.
55    Envelope(EnvelopeError),
56}
57
58/// Other arguments affecting the HUGR CLI runtime.
59#[derive(Parser, Debug)]
60pub struct OtherArgs {
61    /// Verbosity.
62    #[command(flatten)]
63    pub verbose: Verbosity<InfoLevel>,
64}
65
66impl OtherArgs {
67    /// Test whether a `level` message should be output.
68    pub fn verbosity(&self, level: Level) -> bool {
69        self.verbose.log_level_filter() >= level
70    }
71}