hugr_cli/
validate.rs

1//! The `validate` subcommand.
2
3use clap::Parser;
4use clap_verbosity_flag::log::Level;
5use hugr::{extension::ExtensionRegistry, Extension, Hugr};
6
7use crate::{CliError, HugrArgs};
8
9/// Validate and visualise a HUGR file.
10#[derive(Parser, Debug)]
11#[clap(version = "1.0", long_about = None)]
12#[clap(about = "Validate a HUGR.")]
13#[group(id = "hugr")]
14#[non_exhaustive]
15pub struct ValArgs {
16    #[command(flatten)]
17    /// common arguments
18    pub hugr_args: HugrArgs,
19}
20
21/// String to print when validation is successful.
22pub const VALID_PRINT: &str = "HUGR valid!";
23
24impl ValArgs {
25    /// Run the HUGR cli and validate against an extension registry.
26    pub fn run(&mut self) -> Result<Vec<Hugr>, CliError> {
27        let result = self.hugr_args.validate()?;
28        if self.verbosity(Level::Info) {
29            eprintln!("{}", VALID_PRINT);
30        }
31        Ok(result)
32    }
33
34    /// Test whether a `level` message should be output.
35    pub fn verbosity(&self, level: Level) -> bool {
36        self.hugr_args.verbosity(level)
37    }
38}
39
40impl HugrArgs {
41    /// Load the package and validate against an extension registry.
42    ///
43    /// Returns the validated modules and the extension registry the modules
44    /// were validated against.
45    pub fn validate(&mut self) -> Result<Vec<Hugr>, CliError> {
46        let reg = self.extensions()?;
47        let package = self.get_package_or_hugr(&reg)?;
48
49        package.validate()?;
50        Ok(package.into_hugrs())
51    }
52
53    /// Return a register with the selected extensions.
54    pub fn extensions(&self) -> Result<ExtensionRegistry, CliError> {
55        let mut reg = if self.no_std {
56            hugr::extension::PRELUDE_REGISTRY.to_owned()
57        } else {
58            hugr::std_extensions::STD_REG.to_owned()
59        };
60
61        for ext in &self.extensions {
62            let f = std::fs::File::open(ext)?;
63            let ext: Extension = serde_json::from_reader(f)?;
64            reg.register_updated(ext);
65        }
66
67        Ok(reg)
68    }
69
70    /// Test whether a `level` message should be output.
71    pub fn verbosity(&self, level: Level) -> bool {
72        self.verbose.log_level_filter() >= level
73    }
74}