diff options
Diffstat (limited to 'adenosine/src/vendored/iroh_car/header.rs')
-rw-r--r-- | adenosine/src/vendored/iroh_car/header.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/adenosine/src/vendored/iroh_car/header.rs b/adenosine/src/vendored/iroh_car/header.rs new file mode 100644 index 0000000..cd0feb7 --- /dev/null +++ b/adenosine/src/vendored/iroh_car/header.rs @@ -0,0 +1,107 @@ +#![allow(unused)] + +use libipld::cbor::DagCborCodec; +use libipld::codec::Codec; +use libipld::ipld; +use libipld::Cid; + +use super::error::Error; + +/// A car header. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum CarHeader { + V1(CarHeaderV1), +} + +impl CarHeader { + pub fn new_v1(roots: Vec<Cid>) -> Self { + Self::V1(roots.into()) + } + + pub fn decode(buffer: &[u8]) -> Result<Self, Error> { + let header: CarHeaderV1 = DagCborCodec + .decode(buffer) + .map_err(|e| Error::Parsing(e.to_string()))?; + + if header.roots.is_empty() { + return Err(Error::Parsing("empty CAR file".to_owned())); + } + + if header.version != 1 { + return Err(Error::InvalidFile( + "Only CAR file version 1 is supported".to_string(), + )); + } + + Ok(CarHeader::V1(header)) + } + + pub fn encode(&self) -> Result<Vec<u8>, Error> { + match self { + CarHeader::V1(ref header) => { + let res = DagCborCodec.encode(header)?; + Ok(res) + } + } + } + + pub fn roots(&self) -> &[Cid] { + match self { + CarHeader::V1(header) => &header.roots, + } + } + + pub fn version(&self) -> u64 { + match self { + CarHeader::V1(_) => 1, + } + } +} + +/// CAR file header version 1. +#[derive(Debug, Clone, Default, libipld::DagCbor, PartialEq, Eq)] +pub struct CarHeaderV1 { + #[ipld] + pub roots: Vec<Cid>, + #[ipld] + pub version: u64, +} + +impl CarHeaderV1 { + /// Creates a new CAR file header + pub fn new(roots: Vec<Cid>, version: u64) -> Self { + Self { roots, version } + } +} + +impl From<Vec<Cid>> for CarHeaderV1 { + fn from(roots: Vec<Cid>) -> Self { + Self { roots, version: 1 } + } +} + +#[cfg(test)] +mod tests { + use libipld::cbor::DagCborCodec; + use libipld::codec::{Decode, Encode}; + use multihash::MultihashDigest; + + use super::*; + + #[test] + fn symmetric_header_v1() { + let digest = multihash::Code::Blake2b256.digest(b"test"); + let cid = Cid::new_v1(DagCborCodec.into(), digest); + + let header = CarHeaderV1::from(vec![cid]); + + let mut bytes = Vec::new(); + header.encode(DagCborCodec, &mut bytes).unwrap(); + + assert_eq!( + CarHeaderV1::decode(DagCborCodec, &mut std::io::Cursor::new(&bytes)).unwrap(), + header + ); + } +} |