hugr_core/envelope/
package_json.rs1use derive_more::{Display, Error, From};
3use itertools::Itertools;
4use std::io;
5
6use crate::extension::resolution::ExtensionResolutionError;
7use crate::extension::{ExtensionRegistry, PRELUDE_REGISTRY};
8use crate::hugr::ExtensionError;
9use crate::package::Package;
10use crate::{Extension, Hugr, HugrView};
11
12pub(super) fn from_json_reader(
14 reader: impl io::Read,
15 extension_registry: &ExtensionRegistry,
16) -> Result<Package, PackageEncodingError> {
17 let val: serde_json::Value = serde_json::from_reader(reader)?;
18
19 let PackageDeser {
20 modules,
21 extensions: pkg_extensions,
22 } = serde_json::from_value::<PackageDeser>(val.clone())?;
23 let mut modules = modules.into_iter().map(|h| h.0).collect_vec();
24
25 let extension_registry = if PRELUDE_REGISTRY
37 .iter()
38 .any(|e| !extension_registry.contains(&e.name))
39 {
40 let mut reg_with_prelude = extension_registry.clone();
41 reg_with_prelude.extend(PRELUDE_REGISTRY.iter().cloned());
42 reg_with_prelude
43 } else {
44 extension_registry.clone()
45 };
46
47 let mut pkg_extensions = ExtensionRegistry::new_with_extension_resolution(
48 pkg_extensions,
49 &(&extension_registry).into(),
50 )?;
51
52 let mut combined_registry = extension_registry.clone();
54 combined_registry.extend(&pkg_extensions);
55
56 for module in &mut modules {
57 module.resolve_extension_defs(&combined_registry)?;
58 pkg_extensions.extend(module.extensions());
59 }
60
61 Ok(Package {
62 modules,
63 extensions: pkg_extensions,
64 })
65}
66
67pub(super) fn to_json_writer<'h>(
69 hugrs: impl IntoIterator<Item = &'h Hugr>,
70 extensions: &ExtensionRegistry,
71 writer: impl io::Write,
72) -> Result<(), PackageEncodingError> {
73 let pkg_ser = PackageSer {
74 modules: hugrs.into_iter().map(HugrSer).collect(),
75 extensions: extensions.iter().map(|e| e.as_ref()).collect(),
76 };
77 serde_json::to_writer(writer, &pkg_ser)?;
78 Ok(())
79}
80
81#[derive(Debug, Display, Error, From)]
83#[non_exhaustive]
84pub enum PackageEncodingError {
85 JsonEncoding(serde_json::Error),
87 IOError(io::Error),
89 ExtensionResolution(ExtensionResolutionError),
91 RuntimeExtensionResolution(ExtensionError),
93}
94
95#[derive(Debug, serde::Serialize)]
100struct PackageSer<'h> {
101 pub modules: Vec<HugrSer<'h>>,
102 pub extensions: Vec<&'h Extension>,
103}
104#[derive(Debug, serde::Serialize)]
105#[serde(transparent)]
106struct HugrSer<'h>(#[serde(serialize_with = "Hugr::serde_serialize")] pub &'h Hugr);
107
108#[derive(Debug, serde::Deserialize)]
113struct PackageDeser {
114 pub modules: Vec<HugrDeser>,
115 pub extensions: Vec<Extension>,
116}
117#[derive(Debug, serde::Deserialize)]
118#[serde(transparent)]
119struct HugrDeser(#[serde(deserialize_with = "Hugr::serde_deserialize")] pub Hugr);