1use crate::{
2 bounded_reader::{
3 sync::BoundedReader,
4 traits::{Bounded, CloneAndRewind},
5 },
6 dag_pb::{DagPb, DagPbType},
7 traits::ContextLen,
8};
9
10use derivative::Derivative;
11use libipld::Cid;
12
13#[derive(Derivative, derive_more::Debug)]
14#[derivative(Clone(bound = ""))]
15pub enum BlockType<T> {
16 Raw,
17 DagPb(DagPb<T>),
18}
19
20#[derive(Derivative, derive_more::Debug)]
21#[derivative(Clone(bound = ""))]
22pub struct Block<T> {
23 pub cid: Cid,
24 pub r#type: BlockType<T>,
25 pub data: BoundedReader<T>,
26}
27
28impl<T> Block<T> {
29 pub fn new_raw<D>(cid: Cid, data: D) -> Self
30 where
31 D: Into<BoundedReader<T>>,
32 {
33 Self { cid, data: data.into(), r#type: BlockType::Raw }
34 }
35
36 pub fn new_dag_pb<PB, D>(cid: Cid, dag_pb: PB, data: D) -> Self
37 where
38 D: Into<BoundedReader<T>>,
39 PB: Into<DagPb<T>>,
40 {
41 Self { cid, data: data.into(), r#type: BlockType::DagPb(dag_pb.into()) }
42 }
43
44 pub fn dag_pb_type(&self) -> Option<&DagPbType> {
45 match &self.r#type {
46 BlockType::Raw => None,
47 BlockType::DagPb(dag) => Some(&dag.r#type),
48 }
49 }
50
51 pub fn as_sfb_data(&self) -> Option<BoundedReader<T>> {
52 match &self.r#type {
53 BlockType::Raw => Some(self.data.clone_and_rewind()),
54 BlockType::DagPb(dag) => dag.as_sfb_data(),
55 }
56 }
57}
58
59impl<T> ContextLen for Block<T> {
60 fn data_len(&self) -> u64 {
61 match &self.r#type {
62 BlockType::Raw => self.data.bound_len(),
63 BlockType::DagPb(dag_pb) => dag_pb.data_len(),
64 }
65 }
66
67 fn pb_data_len(&self) -> u64 {
68 match &self.r#type {
69 BlockType::Raw => self.data.bound_len(),
70 BlockType::DagPb(dag_pb) => dag_pb.data.bound_len() + self.data.bound_len(),
71 }
72 }
73}