concinnity_core/blob/kind.rs
1// What a .cnb container admits. The metadata type is the container's whole
2// contract -- header layout is shared, the meta type decides what the file can
3// hold -- so the magic that identifies a file belongs to that type rather than
4// to the encode and parse functions. Binding them here makes reading one kind
5// of container as another a type error rather than a runtime check.
6
7use serde::Serialize;
8use serde::de::DeserializeOwned;
9
10use crate::blob::schema::BlobMeta;
11
12/// A `.cnb` container kind: a metadata type paired with the magic bytes that
13/// identify a file carrying it.
14///
15/// Every kind shares the 16-byte header and the payload section after it; only
16/// the metadata block and the meaning of the header's validity token differ:
17/// [`BlobMeta`] is the cooked world, [`CacheMeta`](crate::blob::CacheMeta) a
18/// segment of regenerable cache.
19/// [`encode_cnb`](crate::blob::encode_cnb) and
20/// [`parse_cnb`](crate::blob::parse_cnb) are generic over this trait, so a file
21/// written for one kind cannot be parsed as another: the magic will not match.
22pub trait BlobKind: Serialize + DeserializeOwned {
23 /// The four bytes a file of this kind starts with.
24 const MAGIC: [u8; 4];
25}
26
27impl BlobKind for BlobMeta {
28 const MAGIC: [u8; 4] = crate::blob::BLOB_MAGIC;
29}