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