miden_mast_package/package/
serialization.rs1use alloc::{
23 collections::BTreeMap,
24 format,
25 string::{String, ToString},
26 sync::Arc,
27 vec::Vec,
28};
29
30use miden_assembly_syntax::{
31 Library,
32 ast::{AttributeSet, PathBuf},
33 library::{FunctionTypeDeserializer, FunctionTypeSerializer},
34};
35use miden_core::{
36 Word,
37 program::Program,
38 serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
39};
40
41use super::{ConstantExport, PackageKind, ProcedureExport, TypeExport};
42use crate::{Dependency, MastArtifact, Package, PackageExport, PackageManifest, Section};
43
44const MAGIC_PACKAGE: &[u8; 5] = b"MASP\0";
49
50const MAGIC_PROGRAM: &[u8; 4] = b"PRG\0";
52
53const MAGIC_LIBRARY: &[u8; 4] = b"LIB\0";
55
56const VERSION: [u8; 3] = [3, 0, 0];
60
61impl Serializable for Package {
65 fn write_into<W: ByteWriter>(&self, target: &mut W) {
66 target.write_bytes(MAGIC_PACKAGE);
68 target.write_bytes(&VERSION);
69
70 self.name.write_into(target);
72
73 self.version.as_ref().map(|v| v.to_string()).write_into(target);
75
76 self.description.write_into(target);
78
79 target.write_u8(self.kind.into());
81
82 self.mast.write_into(target);
84
85 self.manifest.write_into(target);
87
88 target.write_usize(self.sections.len());
90 for section in self.sections.iter() {
91 section.write_into(target);
92 }
93 }
94}
95
96impl Deserializable for Package {
97 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
98 let magic: [u8; 5] = source.read_array()?;
100 if magic != *MAGIC_PACKAGE {
101 return Err(DeserializationError::InvalidValue(format!(
102 "invalid magic bytes. Expected '{MAGIC_PACKAGE:?}', got '{magic:?}'"
103 )));
104 }
105
106 let version: [u8; 3] = source.read_array()?;
107 if version != VERSION {
108 return Err(DeserializationError::InvalidValue(format!(
109 "unsupported version. Got '{version:?}', but only '{VERSION:?}' is supported"
110 )));
111 }
112
113 let name = String::read_from(source)?;
115
116 let version = Option::<String>::read_from(source)?;
118 let version = match version {
119 Some(version) => Some(
120 crate::Version::parse(&version)
121 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))?,
122 ),
123 None => None,
124 };
125
126 let description = Option::<String>::read_from(source)?;
128
129 let kind_tag = source.read_u8()?;
131 let kind = PackageKind::try_from(kind_tag)
132 .map_err(|e| DeserializationError::InvalidValue(e.to_string()))?;
133
134 let mast = MastArtifact::read_from(source)?;
136
137 let manifest = PackageManifest::read_from(source)?;
139
140 let num_sections = source.read_usize()?;
142 let mut sections = Vec::with_capacity(num_sections);
143 for _ in 0..num_sections {
144 let section = Section::read_from(source)?;
145 sections.push(section);
146 }
147
148 Ok(Self {
149 name,
150 version,
151 description,
152 kind,
153 mast,
154 manifest,
155 sections,
156 })
157 }
158}
159
160impl Serializable for MastArtifact {
164 fn write_into<W: ByteWriter>(&self, target: &mut W) {
165 match self {
166 Self::Executable(program) => {
167 target.write_bytes(MAGIC_PROGRAM);
168 program.write_into(target);
169 },
170 Self::Library(library) => {
171 target.write_bytes(MAGIC_LIBRARY);
172 library.write_into(target);
173 },
174 }
175 }
176}
177
178impl Deserializable for MastArtifact {
179 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
180 let tag: [u8; 4] = source.read_array()?;
181
182 if &tag == MAGIC_PROGRAM {
183 Program::read_from(source).map(Arc::new).map(MastArtifact::Executable)
184 } else if &tag == MAGIC_LIBRARY {
185 Library::read_from(source).map(Arc::new).map(MastArtifact::Library)
186 } else {
187 Err(DeserializationError::InvalidValue(format!(
188 "invalid MAST artifact tag: {:?}",
189 &tag
190 )))
191 }
192 }
193}
194
195#[cfg(feature = "serde")]
199impl serde::Serialize for PackageManifest {
200 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
201 where
202 S: serde::Serializer,
203 {
204 use miden_assembly_syntax::Path;
205 use serde::ser::SerializeStruct;
206
207 struct PackageExports<'a>(&'a BTreeMap<Arc<Path>, PackageExport>);
208
209 impl serde::Serialize for PackageExports<'_> {
210 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
211 where
212 S: serde::Serializer,
213 {
214 use serde::ser::SerializeSeq;
215
216 let mut serializer = serializer.serialize_seq(Some(self.0.len()))?;
217 for value in self.0.values() {
218 serializer.serialize_element(value)?;
219 }
220 serializer.end()
221 }
222 }
223
224 let mut serializer = serializer.serialize_struct("PackageManifest", 2)?;
225 serializer.serialize_field("exports", &PackageExports(&self.exports))?;
226 serializer.serialize_field("dependencies", &self.dependencies)?;
227 serializer.end()
228 }
229}
230
231#[cfg(feature = "serde")]
232impl<'de> serde::Deserialize<'de> for PackageManifest {
233 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
234 where
235 D: serde::Deserializer<'de>,
236 {
237 #[derive(serde::Deserialize)]
238 #[serde(field_identifier, rename_all = "lowercase")]
239 enum Field {
240 Exports,
241 Dependencies,
242 }
243
244 struct PackageManifestVisitor;
245
246 impl<'de> serde::de::Visitor<'de> for PackageManifestVisitor {
247 type Value = PackageManifest;
248
249 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
250 formatter.write_str("struct PackageManifest")
251 }
252
253 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
254 where
255 A: serde::de::SeqAccess<'de>,
256 {
257 let exports = seq
258 .next_element::<Vec<PackageExport>>()?
259 .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
260 let dependencies = seq
261 .next_element::<Vec<Dependency>>()?
262 .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
263 Ok(PackageManifest::new(exports).with_dependencies(dependencies))
264 }
265
266 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
267 where
268 A: serde::de::MapAccess<'de>,
269 {
270 let mut exports = None;
271 let mut dependencies = None;
272 while let Some(key) = map.next_key()? {
273 match key {
274 Field::Exports => {
275 if exports.is_some() {
276 return Err(serde::de::Error::duplicate_field("exports"));
277 }
278 exports = Some(map.next_value::<Vec<PackageExport>>()?);
279 },
280 Field::Dependencies => {
281 if dependencies.is_some() {
282 return Err(serde::de::Error::duplicate_field("dependencies"));
283 }
284 dependencies = Some(map.next_value::<Vec<Dependency>>()?);
285 },
286 }
287 }
288 let exports = exports.ok_or_else(|| serde::de::Error::missing_field("exports"))?;
289 let dependencies =
290 dependencies.ok_or_else(|| serde::de::Error::missing_field("dependencies"))?;
291 Ok(PackageManifest::new(exports).with_dependencies(dependencies))
292 }
293 }
294
295 deserializer.deserialize_struct(
296 "PackageManifest",
297 &["exports", "dependencies"],
298 PackageManifestVisitor,
299 )
300 }
301}
302
303impl Serializable for PackageManifest {
304 fn write_into<W: ByteWriter>(&self, target: &mut W) {
305 target.write_usize(self.num_exports());
307 for export in self.exports() {
308 export.write_into(target);
309 }
310
311 target.write_usize(self.num_dependencies());
313 for dep in self.dependencies() {
314 dep.write_into(target);
315 }
316 }
317}
318
319impl Deserializable for PackageManifest {
320 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
321 let exports_len = source.read_usize()?;
323 let mut exports = BTreeMap::new();
324 for _ in 0..exports_len {
325 let export = PackageExport::read_from(source)?;
326 exports.insert(export.path().clone(), export);
327 }
328
329 let deps_len = source.read_usize()?;
331 let mut dependencies = Vec::with_capacity(deps_len);
332 for _ in 0..deps_len {
333 dependencies.push(Dependency::read_from(source)?);
334 }
335
336 Ok(Self { exports, dependencies })
337 }
338}
339
340impl Serializable for PackageExport {
343 fn write_into<W: ByteWriter>(&self, target: &mut W) {
344 target.write_u8(self.tag());
345 match self {
346 Self::Procedure(export) => export.write_into(target),
347 Self::Constant(export) => export.write_into(target),
348 Self::Type(export) => export.write_into(target),
349 }
350 }
351}
352
353impl Deserializable for PackageExport {
354 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
355 match source.read_u8()? {
356 1 => ProcedureExport::read_from(source).map(Self::Procedure),
357 2 => ConstantExport::read_from(source).map(Self::Constant),
358 3 => TypeExport::read_from(source).map(Self::Type),
359 invalid => Err(DeserializationError::InvalidValue(format!(
360 "unexpected PackageExport tag: '{invalid}'"
361 ))),
362 }
363 }
364}
365
366impl Serializable for ProcedureExport {
367 fn write_into<W: ByteWriter>(&self, target: &mut W) {
368 self.path.write_into(target);
369 self.digest.write_into(target);
370 match self.signature.as_ref() {
371 Some(sig) => {
372 target.write_bool(true);
373 FunctionTypeSerializer(sig).write_into(target);
374 },
375 None => {
376 target.write_bool(false);
377 },
378 }
379 self.attributes.write_into(target);
380 }
381}
382
383impl Deserializable for ProcedureExport {
384 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
385 let path = PathBuf::read_from(source)?.into_boxed_path().into();
386 let digest = Word::read_from(source)?;
387 let signature = if source.read_bool()? {
388 Some(FunctionTypeDeserializer::read_from(source)?.0)
389 } else {
390 None
391 };
392 let attributes = AttributeSet::read_from(source)?;
393 Ok(Self { path, digest, signature, attributes })
394 }
395}
396
397impl Serializable for ConstantExport {
398 fn write_into<W: ByteWriter>(&self, target: &mut W) {
399 self.path.write_into(target);
400 self.value.write_into(target);
401 }
402}
403
404impl Deserializable for ConstantExport {
405 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
406 let path = PathBuf::read_from(source)?.into_boxed_path().into();
407 let value = miden_assembly_syntax::ast::ConstantValue::read_from(source)?;
408 Ok(Self { path, value })
409 }
410}
411
412impl Serializable for TypeExport {
413 fn write_into<W: ByteWriter>(&self, target: &mut W) {
414 use miden_assembly_syntax::library::TypeSerializer;
415
416 self.path.write_into(target);
417 TypeSerializer(&self.ty).write_into(target);
418 }
419}
420
421impl Deserializable for TypeExport {
422 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
423 use miden_assembly_syntax::library::TypeDeserializer;
424
425 let path = PathBuf::read_from(source)?.into_boxed_path().into();
426 let ty = TypeDeserializer::read_from(source)?.0;
427 Ok(Self { path, ty })
428 }
429}