diff options
author | Bryan Newbold <bnewbold@robocracy.org> | 2022-11-06 21:44:13 -0800 |
---|---|---|
committer | Bryan Newbold <bnewbold@robocracy.org> | 2022-11-06 21:44:14 -0800 |
commit | 6111c481fac3d5c305a379b3be8afb87190db3d5 (patch) | |
tree | 4232ed843813cd9661ab16e25ccb7a05611fb2a2 /adenosine-pds/src/vendored/iroh_car/header.rs | |
parent | 40cb22e75314f73b1f9292190b786ac04fc58b67 (diff) | |
download | adenosine-6111c481fac3d5c305a379b3be8afb87190db3d5.tar.gz adenosine-6111c481fac3d5c305a379b3be8afb87190db3d5.zip |
iroh-car: move vendoring into sub-module of pds crate
So we don't need to re-publish this as a separate crate.
Diffstat (limited to 'adenosine-pds/src/vendored/iroh_car/header.rs')
-rw-r--r-- | adenosine-pds/src/vendored/iroh_car/header.rs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/adenosine-pds/src/vendored/iroh_car/header.rs b/adenosine-pds/src/vendored/iroh_car/header.rs new file mode 100644 index 0000000..c004e35 --- /dev/null +++ b/adenosine-pds/src/vendored/iroh_car/header.rs @@ -0,0 +1,104 @@ +use cid::Cid; +use ipld::codec::Codec; +use ipld_cbor::DagCborCodec; + +use crate::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, ipld::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 ipld::codec::{Decode, Encode}; + use ipld_cbor::DagCborCodec; + 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 + ); + } +} |