1use clio::Input;
4use hugr::envelope::description::PackageDesc;
5use hugr::envelope::{EnvelopeConfig, read_described_envelope};
6use hugr::extension::ExtensionRegistry;
7use hugr::package::Package;
8use hugr::{Extension, Hugr};
9use std::io::{BufReader, Read};
10use std::path::PathBuf;
11
12use crate::CliError;
13
14#[derive(Debug, clap::Args)]
16pub struct HugrInputArgs {
17 #[arg(value_parser, default_value = "-", help_heading = "Input")]
19 pub input: Input,
20
21 #[arg(
23 long,
24 help_heading = "Input",
25 help = "Don't use standard extensions when validating hugrs. Prelude is still used."
26 )]
27 pub no_std: bool,
28 #[arg(
30 short,
31 long,
32 help_heading = "Input",
33 help = "Paths to additional serialised extensions needed to load the Hugr."
34 )]
35 pub extensions: Vec<PathBuf>,
36 #[clap(long, help_heading = "Input")]
40 pub hugr_json: bool,
41}
42
43impl HugrInputArgs {
44 pub fn get_package(&mut self) -> Result<Package, CliError> {
52 self.get_described_package().map(|(_, package)| package)
53 }
54
55 #[deprecated(since = "0.24.1", note = "Use get_described_envelope instead")]
63 pub fn get_envelope(&mut self) -> Result<(EnvelopeConfig, Package), CliError> {
64 let (desc, package) = self.get_described_package()?;
65 Ok((desc.header.config(), package))
66 }
67
68 pub fn get_described_package(&mut self) -> Result<(PackageDesc, Package), CliError> {
76 let extensions = self.load_extensions()?;
77 let buffer = BufReader::new(&mut self.input);
78
79 Ok(read_described_envelope(buffer, &extensions)?)
80 }
81 #[deprecated(note = "Use `HugrInputArgs::get_package` instead.", since = "0.22.2")]
88 pub fn get_hugr(&mut self) -> Result<Hugr, CliError> {
89 let extensions = self.load_extensions()?;
90 let mut buffer = BufReader::new(&mut self.input);
91
92 const PREPEND: &str = r#"HUGRiHJv?@{"modules": ["#;
94 const APPEND: &str = r#"],"extensions": []}"#;
95
96 let mut envelope = PREPEND.to_string();
97 buffer.read_to_string(&mut envelope)?;
98 envelope.push_str(APPEND);
99
100 let hugr = Hugr::load_str(envelope, Some(&extensions))?;
101 Ok(hugr)
102 }
103
104 pub fn load_extensions(&self) -> Result<ExtensionRegistry, CliError> {
109 let mut reg = if self.no_std {
110 hugr::extension::PRELUDE_REGISTRY.to_owned()
111 } else {
112 hugr::std_extensions::STD_REG.to_owned()
113 };
114
115 for ext in &self.extensions {
116 let f = std::fs::File::open(ext)?;
117 let ext: Extension = serde_json::from_reader(f)?;
118 reg.register_updated(ext);
119 }
120
121 Ok(reg)
122 }
123}