carbites 0.1.2

CAR file splitted implementation in Rust
Documentation
use ipld::{prelude::Codec, Cid};
use ipld_cbor::DagCborCodec;
use std::io::{Read, Seek};

use crate::error::CarSplitterError;
use crate::reader::read_block;

#[derive(Debug, Clone, PartialEq, Eq, Default, ipld::DagCbor)]
pub(crate) struct CarHeader {
    #[ipld]
    pub roots: Vec<Cid>,
    #[ipld]
    pub version: u64,
}

impl CarHeader {
    pub fn new(roots: Vec<Cid>) -> Self {
        Self { roots, version: 1 }
    }

    pub fn read_header<R>(r: R) -> Result<CarHeader, CarSplitterError>
    where
        R: Read + Seek,
    {
        let data = match read_block(r) {
            Ok(Some(d)) => d,
            Ok(None) => return Err(CarSplitterError::Parsing("invalid Header".into())),
            Err(e) => return Err(e),
        };
        let header = CarHeader::decode(&data[..])?;
        Ok(header)
    }

    pub fn decode(buf: &[u8]) -> Result<CarHeader, CarSplitterError> {
        let header: CarHeader = DagCborCodec
            .decode(buf)
            .map_err(|e| CarSplitterError::Parsing(e.to_string()))?;
        if header.roots.is_empty() {
            return Err(CarSplitterError::Parsing("CAR roots is empty".to_owned()));
        }
        if header.version != 1 {
            return Err(CarSplitterError::InvalidFile(
                "CAR version 1 is supported only".to_string(),
            ));
        }
        Ok(header)
    }

    pub fn encode(&self) -> Result<Vec<u8>, CarSplitterError> {
        let data = DagCborCodec
            .encode(self)
            .map_err(|e| CarSplitterError::Parsing(e.to_string()))?;
        Ok(data)
    }
}

#[cfg(test)]
mod test {

    #[test]
    fn test() {
        todo!("test");
    }
}