Skip to main content

vfs/package_format/
versioned.rs

1use anyhow::{bail, Context, Result};
2use vbare::OwnedVersionedData;
3
4use super::generated::v1;
5
6pub const PACKAGE_MANIFEST_VERSION: u16 = 1;
7
8pub enum PackageManifest {
9    V1(v1::PackageManifest),
10}
11
12impl OwnedVersionedData for PackageManifest {
13    type Latest = v1::PackageManifest;
14
15    fn wrap_latest(latest: Self::Latest) -> Self {
16        Self::V1(latest)
17    }
18
19    fn unwrap_latest(self) -> Result<Self::Latest> {
20        match self {
21            Self::V1(data) => Ok(data),
22        }
23    }
24
25    fn deserialize_version(payload: &[u8], version: u16) -> Result<Self> {
26        match version {
27            PACKAGE_MANIFEST_VERSION => Ok(Self::V1(serde_bare::from_slice(payload)?)),
28            _ => bail!("invalid package manifest version: {version}"),
29        }
30    }
31
32    fn serialize_version(self, _version: u16) -> Result<Vec<u8>> {
33        match self {
34            Self::V1(data) => serde_bare::to_vec(&data).map_err(Into::into),
35        }
36    }
37}
38
39pub enum MountIndex {
40    V1(v1::MountIndex),
41}
42
43impl OwnedVersionedData for MountIndex {
44    type Latest = v1::MountIndex;
45
46    fn wrap_latest(latest: Self::Latest) -> Self {
47        Self::V1(latest)
48    }
49
50    fn unwrap_latest(self) -> Result<Self::Latest> {
51        match self {
52            Self::V1(data) => Ok(data),
53        }
54    }
55
56    fn deserialize_version(payload: &[u8], version: u16) -> Result<Self> {
57        match version {
58            PACKAGE_MANIFEST_VERSION => Ok(Self::V1(serde_bare::from_slice(payload)?)),
59            _ => bail!("invalid package mount index version: {version}"),
60        }
61    }
62
63    fn serialize_version(self, _version: u16) -> Result<Vec<u8>> {
64        match self {
65            Self::V1(data) => serde_bare::to_vec(&data).map_err(Into::into),
66        }
67    }
68}
69
70/// Encode the latest package manifest with an embedded 2-byte schema version.
71pub fn encode_package_manifest(manifest: v1::PackageManifest) -> Result<Vec<u8>> {
72    PackageManifest::wrap_latest(manifest)
73        .serialize_with_embedded_version(PACKAGE_MANIFEST_VERSION)
74        .context("encode package manifest")
75}
76
77/// Decode a versioned package manifest payload into the latest schema variant.
78pub fn decode_package_manifest(payload: &[u8]) -> Result<v1::PackageManifest> {
79    PackageManifest::deserialize_with_embedded_version(payload).context("decode package manifest")
80}
81
82/// Encode the latest package mount index with an embedded 2-byte schema version.
83pub fn encode_mount_index(index: v1::MountIndex) -> Result<Vec<u8>> {
84    MountIndex::wrap_latest(index)
85        .serialize_with_embedded_version(PACKAGE_MANIFEST_VERSION)
86        .context("encode package mount index")
87}
88
89/// Decode a versioned package mount index payload into the latest schema variant.
90pub fn decode_mount_index(payload: &[u8]) -> Result<v1::MountIndex> {
91    MountIndex::deserialize_with_embedded_version(payload).context("decode package mount index")
92}