4141// https://github.com/JelteF/derive_more/pull/454.
4242
4343mod header;
44+ mod package_json;
45+ pub mod serde_with;
4446
4547pub use header:: { EnvelopeConfig , EnvelopeFormat , ZstdConfig , MAGIC_NUMBERS } ;
48+ pub use package_json:: PackageEncodingError ;
4649
47- use crate :: {
48- extension:: ExtensionRegistry ,
49- package:: { Package , PackageEncodingError } ,
50- } ;
50+ use crate :: Hugr ;
51+ use crate :: { extension:: ExtensionRegistry , package:: Package } ;
5152use header:: EnvelopeHeader ;
5253use std:: io:: BufRead ;
5354use std:: io:: Write ;
@@ -90,9 +91,22 @@ pub fn read_envelope(
9091/// It is recommended to use a buffered writer for better performance.
9192/// See [`std::io::BufWriter`] for more information.
9293pub fn write_envelope (
93- mut writer : impl Write ,
94+ writer : impl Write ,
9495 package : & Package ,
9596 config : EnvelopeConfig ,
97+ ) -> Result < ( ) , EnvelopeError > {
98+ write_envelope_impl ( writer, & package. modules , & package. extensions , config)
99+ }
100+
101+ /// Write a deconstructed HUGR package into an envelope, using the specified configuration.
102+ ///
103+ /// It is recommended to use a buffered writer for better performance.
104+ /// See [`std::io::BufWriter`] for more information.
105+ pub ( crate ) fn write_envelope_impl < ' h > (
106+ mut writer : impl Write ,
107+ hugrs : impl IntoIterator < Item = & ' h Hugr > ,
108+ extensions : & ExtensionRegistry ,
109+ config : EnvelopeConfig ,
96110) -> Result < ( ) , EnvelopeError > {
97111 let header = config. make_header ( ) ;
98112 header. write ( & mut writer) ?;
@@ -101,11 +115,11 @@ pub fn write_envelope(
101115 #[ cfg( feature = "zstd" ) ]
102116 Some ( zstd) => {
103117 let writer = zstd:: Encoder :: new ( writer, zstd. level ( ) ) ?. auto_finish ( ) ;
104- write_impl ( writer, package , config) ?;
118+ write_impl ( writer, hugrs , extensions , config) ?;
105119 }
106120 #[ cfg( not( feature = "zstd" ) ) ]
107121 Some ( _) => return Err ( EnvelopeError :: ZstdUnsupported ) ,
108- None => write_impl ( writer, package , config) ?,
122+ None => write_impl ( writer, hugrs , extensions , config) ?,
109123 }
110124
111125 Ok ( ( ) )
@@ -164,14 +178,14 @@ pub enum EnvelopeError {
164178 #[ display( "Zstd compression is not supported. This requires the 'zstd' feature for `hugr`." ) ]
165179 #[ from( ignore) ]
166180 ZstdUnsupported ,
167- /// Tried to encode a package with multiple HUGRs, when only 1 was expected.
168- #[ display(
169- "Packages with multiple HUGRs are currently unsupported. Tried to encode {count} HUGRs, when 1 was expected."
170- ) ]
181+ /// Expected the envelope to contain a single HUGR.
182+ #[ display( "Expected an envelope containing a single hugr, but it contained {}." , if * count == 0 {
183+ "none" . to_string( )
184+ } else {
185+ count. to_string( )
186+ } ) ]
171187 #[ from( ignore) ]
172- /// Deprecated: Packages with multiple HUGRs is a legacy feature that is no longer supported.
173- #[ deprecated( since = "0.15.2" , note = "Multiple HUGRs are supported via packages." ) ]
174- MultipleHugrs {
188+ ExpectedSingleHugr {
175189 /// The number of HUGRs in the package.
176190 count : usize ,
177191 } ,
@@ -215,7 +229,7 @@ fn read_impl(
215229) -> Result < Package , EnvelopeError > {
216230 match header. format {
217231 #[ allow( deprecated) ]
218- EnvelopeFormat :: PackageJson => Ok ( Package :: from_json_reader ( payload, registry) ?) ,
232+ EnvelopeFormat :: PackageJson => Ok ( package_json :: from_json_reader ( payload, registry) ?) ,
219233 EnvelopeFormat :: Model | EnvelopeFormat :: ModelWithExtensions => {
220234 decode_model ( payload, registry, header. format )
221235 }
@@ -260,24 +274,26 @@ fn decode_model(
260274}
261275
262276/// Internal implementation of [`write_envelope`] to call with/without the zstd compression wrapper.
263- fn write_impl (
277+ fn write_impl < ' h > (
264278 writer : impl Write ,
265- package : & Package ,
279+ hugrs : impl IntoIterator < Item = & ' h Hugr > ,
280+ extensions : & ExtensionRegistry ,
266281 config : EnvelopeConfig ,
267282) -> Result < ( ) , EnvelopeError > {
268283 match config. format {
269284 #[ allow( deprecated) ]
270- EnvelopeFormat :: PackageJson => package . to_json_writer ( writer) ?,
285+ EnvelopeFormat :: PackageJson => package_json :: to_json_writer ( hugrs , extensions , writer) ?,
271286 EnvelopeFormat :: Model | EnvelopeFormat :: ModelWithExtensions => {
272- encode_model ( writer, package , config. format ) ?
287+ encode_model ( writer, hugrs , extensions , config. format ) ?
273288 }
274289 }
275290 Ok ( ( ) )
276291}
277292
278- fn encode_model (
293+ fn encode_model < ' h > (
279294 mut writer : impl Write ,
280- package : & Package ,
295+ hugrs : impl IntoIterator < Item = & ' h Hugr > ,
296+ extensions : & ExtensionRegistry ,
281297 format : EnvelopeFormat ,
282298) -> Result < ( ) , EnvelopeError > {
283299 use hugr_model:: v0:: { binary:: write_to_writer, bumpalo:: Bump } ;
@@ -292,11 +308,11 @@ fn encode_model(
292308 }
293309
294310 let bump = Bump :: default ( ) ;
295- let model_package = export_package ( package , & bump) ;
311+ let model_package = export_package ( hugrs , extensions , & bump) ;
296312 write_to_writer ( & model_package, & mut writer) ?;
297313
298314 if format. append_extensions ( ) {
299- serde_json:: to_writer ( writer, & package . extensions . iter ( ) . collect_vec ( ) ) ?;
315+ serde_json:: to_writer ( writer, & extensions. iter ( ) . collect_vec ( ) ) ?;
300316 }
301317
302318 Ok ( ( ) )
0 commit comments