ipld-car 0.1.0

DAG-PB serialization/deserialization library for IPFS CAR v1 archives
Documentation
use crate::{
	ensure,
	error::{Error, InvalidErr, Result},
};

use derive_more::Constructor;
use libipld::Cid;
use std::{
	io::{Read, Seek},
	ops::Range,
};

#[derive(Constructor, PartialEq, Eq, derive_more::Debug, Clone)]
pub struct BlockDef {
	#[debug("{}", cid.to_string())]
	pub cid: Cid,
	pub range: Range<u64>,
	pub car_overhead_byte_counter: u64,
}

impl BlockDef {
	pub fn load<R: Read + Seek>(reader: &mut R) -> Result<Option<Self>> {
		let block_def_start = reader.stream_position()?;
		let Ok(section_len) = leb128::read::unsigned(reader) else { return Ok(None) };

		let cid_start = reader.stream_position()?;
		let cid = Cid::read_bytes(&mut *reader).map_err(InvalidErr::from)?;

		let data_start = reader.stream_position()?;
		let encoded_cid_len = data_start - cid_start;
		ensure!(section_len >= encoded_cid_len, InvalidErr::BlockLen);

		let range = data_start..cid_start.checked_add(section_len).ok_or(Error::FileTooLarge)?;
		let car_overhead_byte_counter = data_start - block_def_start;
		Ok(Some(Self { cid, range, car_overhead_byte_counter }))
	}
}