Skip to content

Commit 7e48e3a

Browse files
committed
Packages and envelopes for hugr-model.
1 parent 25df063 commit 7e48e3a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+531
-79
lines changed

hugr-core/src/envelope.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,6 @@ pub enum EnvelopeError {
159159
#[display("Zstd compression is not supported. This requires the 'zstd' feature for `hugr`.")]
160160
#[from(ignore)]
161161
ZstdUnsupported,
162-
/// Tried to encode a package with multiple HUGRs, when only 1 was expected.
163-
#[display(
164-
"Packages with multiple HUGRs are currently unsupported. Tried to encode {count} HUGRs, when 1 was expected."
165-
)]
166-
#[from(ignore)]
167-
MultipleHugrs {
168-
/// The number of HUGRs in the package.
169-
count: usize,
170-
},
171162
/// JSON serialization error.
172163
SerdeError {
173164
/// The source error.
@@ -244,7 +235,7 @@ fn decode_model(
244235
extension_registry: &ExtensionRegistry,
245236
format: EnvelopeFormat,
246237
) -> Result<Package, EnvelopeError> {
247-
use crate::{import::import_hugr, Extension};
238+
use crate::Extension;
248239
use hugr_model::v0::bumpalo::Bump;
249240

250241
if format.model_version() != Some(0) {
@@ -255,7 +246,7 @@ fn decode_model(
255246
}
256247

257248
let bump = Bump::default();
258-
let module_list = hugr_model::v0::binary::read_from_reader(&mut stream, &bump)?;
249+
let model_package = hugr_model::v0::binary::read_from_reader(&mut stream, &bump)?;
259250

260251
let mut extension_registry = extension_registry.clone();
261252
if format.append_extensions() {
@@ -266,9 +257,7 @@ fn decode_model(
266257
}
267258
}
268259

269-
// TODO: Import multiple hugrs from the model?
270-
let hugr = import_hugr(&module_list, &extension_registry)?;
271-
Ok(Package::new([hugr])?)
260+
Ok(Package::from_model(&model_package, &extension_registry)?)
272261
}
273262

274263
/// Internal implementation of [`write_envelope`] to call with/without the zstd compression wrapper.
@@ -301,7 +290,6 @@ fn encode_model(
301290
package: &Package,
302291
format: EnvelopeFormat,
303292
) -> Result<(), EnvelopeError> {
304-
use crate::export::export_hugr;
305293
use hugr_model::v0::{binary::write_to_writer, bumpalo::Bump};
306294

307295
if format.model_version() != Some(0) {
@@ -311,15 +299,9 @@ fn encode_model(
311299
});
312300
}
313301

314-
// TODO: Export multiple hugrs to the model?
315-
if package.modules.len() != 1 {
316-
return Err(EnvelopeError::MultipleHugrs {
317-
count: package.modules.len(),
318-
});
319-
}
320302
let bump = Bump::default();
321-
let module = export_hugr(&package.modules[0], &bump);
322-
write_to_writer(&module, &mut writer)?;
303+
let model_package = package.to_model(&bump);
304+
write_to_writer(&model_package, &mut writer)?;
323305

324306
if format.append_extensions() {
325307
serde_json::to_writer(writer, &package.extensions.iter().collect_vec())?;

hugr-core/src/export.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use petgraph::unionfind::UnionFind;
2828
use std::fmt::Write;
2929

3030
/// Export a [`Hugr`] graph to its representation in the model.
31-
pub fn export_hugr<'a>(hugr: &'a Hugr, bump: &'a Bump) -> table::Module<'a> {
31+
pub(crate) fn export_hugr<'a>(hugr: &'a Hugr, bump: &'a Bump) -> table::Module<'a> {
3232
let mut ctx = Context::new(hugr, bump);
3333
ctx.export_root();
3434
ctx.module

hugr-core/src/hugr.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ use crate::ops::{OpTag, OpTrait};
3434
pub use crate::ops::{OpType, DEFAULT_OPTYPE};
3535
use crate::{Direction, Node};
3636

37+
#[cfg(feature = "model_unstable")]
38+
use crate::export::export_hugr;
39+
#[cfg(feature = "model_unstable")]
40+
use crate::import::{import_hugr, ImportError};
41+
#[cfg(feature = "model_unstable")]
42+
use hugr_model::v0 as model;
43+
3744
/// The Hugr data structure.
3845
#[derive(Clone, Debug, PartialEq)]
3946
pub struct Hugr {
@@ -256,6 +263,21 @@ impl Hugr {
256263
self.extensions = used_extensions;
257264
Ok(())
258265
}
266+
267+
/// Export this module to the model representation.
268+
#[cfg(feature = "model_unstable")]
269+
pub fn to_model<'a>(&'a self, bump: &'a model::bumpalo::Bump) -> model::table::Module<'a> {
270+
export_hugr(self, bump)
271+
}
272+
273+
/// Import a module from the model representation.
274+
#[cfg(feature = "model_unstable")]
275+
pub fn from_model<'a>(
276+
module: &'a model::table::Module<'a>,
277+
extensions: &ExtensionRegistry,
278+
) -> Result<Self, ImportError> {
279+
import_hugr(module, extensions)
280+
}
259281
}
260282

261283
/// Internal API for HUGRs, not intended for use by users.

hugr-core/src/import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ macro_rules! error_uninferred {
8080
}
8181

8282
/// Import a `hugr` module from its model representation.
83-
pub fn import_hugr(
83+
pub(crate) fn import_hugr(
8484
module: &table::Module,
8585
extensions: &ExtensionRegistry,
8686
) -> Result<Hugr, ImportError> {

hugr-core/src/package.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ use crate::hugr::{ExtensionError, HugrView, ValidationError};
1414
use crate::ops::{FuncDefn, Module, NamedOp, OpTag, OpTrait, OpType};
1515
use crate::{Extension, Hugr};
1616

17+
#[cfg(feature = "model_unstable")]
18+
use crate::import::ImportError;
19+
#[cfg(feature = "model_unstable")]
20+
use hugr_model::v0 as model;
21+
1722
#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
1823
/// Package of module HUGRs.
1924
pub struct Package {
@@ -308,6 +313,34 @@ impl Package {
308313
#[allow(deprecated)]
309314
self.to_json_writer(writer)
310315
}
316+
317+
/// Export this package to the model representation.
318+
#[cfg(feature = "model_unstable")]
319+
pub fn to_model<'a>(&'a self, bump: &'a model::bumpalo::Bump) -> model::table::Package<'a> {
320+
let modules = self
321+
.modules
322+
.iter()
323+
.map(|module| module.to_model(bump))
324+
.collect();
325+
model::table::Package { modules }
326+
}
327+
328+
/// Import a package from the model representation.
329+
#[cfg(feature = "model_unstable")]
330+
pub fn from_model<'a>(
331+
package: &'a model::table::Package<'a>,
332+
extensions: &ExtensionRegistry,
333+
) -> Result<Self, ImportError> {
334+
let modules = package
335+
.modules
336+
.iter()
337+
.map(|module| Hugr::from_model(module, extensions))
338+
.collect::<Result<Vec<_>, _>>()?;
339+
340+
// This does not panic since the import already requires a module root.
341+
let package = Self::new(modules).expect("non-module root");
342+
Ok(package)
343+
}
311344
}
312345

313346
impl AsRef<[Hugr]> for Package {

hugr-core/tests/model.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22

33
use std::str::FromStr;
44

5-
use hugr::std_extensions::std_reg;
6-
use hugr_core::{export::export_hugr, import::import_hugr};
5+
use hugr::{package::Package, std_extensions::std_reg};
76
use hugr_model::v0 as model;
87

98
fn roundtrip(source: &str) -> String {
109
let bump = model::bumpalo::Bump::new();
11-
let module_ast = model::ast::Module::from_str(source).unwrap();
12-
let module_table = module_ast.resolve(&bump).unwrap();
13-
let hugr = import_hugr(&module_table, &std_reg()).unwrap();
14-
let exported_table = export_hugr(&hugr, &bump);
10+
let package_ast = model::ast::Package::from_str(source).unwrap();
11+
let package_table = package_ast.resolve(&bump).unwrap();
12+
let core = Package::from_model(&package_table, &std_reg()).unwrap();
13+
let exported_table = core.to_model(&bump);
1514
let exported_ast = exported_table.as_ast().unwrap();
1615
exported_ast.to_string()
1716
}

hugr-core/tests/snapshots/model__roundtrip_add.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-add.
44
---
55
(hugr 0)
66

7+
(mod)
8+
79
(import core.fn)
810

911
(import arithmetic.int.iadd)

hugr-core/tests/snapshots/model__roundtrip_alias.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-alia
44
---
55
(hugr 0)
66

7+
(mod)
8+
79
(import core.fn)
810

911
(import arithmetic.int.types.int)

hugr-core/tests/snapshots/model__roundtrip_call.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-call
44
---
55
(hugr 0)
66

7+
(mod)
8+
79
(import core.call)
810

911
(import core.load_const)

hugr-core/tests/snapshots/model__roundtrip_cfg.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ expression: "roundtrip(include_str!(\"../../hugr-model/tests/fixtures/model-cfg.
44
---
55
(hugr 0)
66

7+
(mod)
8+
79
(import core.make_adt)
810

911
(import core.ctrl)

0 commit comments

Comments
 (0)