co_primitives/library/
block_serializer.rs1use crate::{from_cbor, to_cbor, Block, KnownMultiCodec, StoreParams};
5use cid::Cid;
6use serde::Serialize;
7
8#[derive(Debug, thiserror::Error)]
9pub enum BlockSerializerError {
10 #[error("Block size {1} exceeds {0}.")]
11 BlockToLarge(usize, usize),
12
13 #[error("Serialize failed")]
14 Serialize(#[source] anyhow::Error),
15
16 #[error("Deserialize {0} as CBOR failed")]
17 Deserialize(Cid, #[source] anyhow::Error),
18}
19
20pub struct BlockSerializer {
22 codec: u64,
23 max_block_size: Option<usize>,
24}
25impl BlockSerializer {
26 pub fn new() -> Self {
27 Self::new_codec(KnownMultiCodec::DagCbor)
28 }
29
30 pub fn new_store_params<P: StoreParams>() -> Self {
31 Self::new_codec(KnownMultiCodec::DagCbor).with_max_block_size(P::MAX_BLOCK_SIZE)
32 }
33
34 pub fn new_codec(codec: impl Into<u64>) -> Self {
35 Self { max_block_size: None, codec: codec.into() }
36 }
37
38 pub fn with_codec(mut self, codec: impl Into<u64>) -> Self {
39 self.codec = codec.into();
40 self
41 }
42
43 pub fn with_max_block_size(mut self, max_block_size: usize) -> Self {
44 self.max_block_size = Some(max_block_size);
45 self
46 }
47}
48impl Default for BlockSerializer {
49 fn default() -> Self {
50 Self::new()
51 }
52}
53impl BlockSerializer {
54 pub fn serialize<T>(&self, item: &T) -> Result<Block, BlockSerializerError>
56 where
57 T: Serialize,
58 {
59 let data = to_cbor(item).map_err(|err| BlockSerializerError::Serialize(err.into()))?;
60 if let Some(max_block_size) = self.max_block_size {
61 if max_block_size < data.len() {
62 return Err(BlockSerializerError::BlockToLarge(max_block_size, data.len()));
63 }
64 }
65 Ok(Block::new_data(self.codec, data))
66 }
67
68 pub fn deserialize<'a, T>(&self, item: &'a Block) -> Result<T, BlockSerializerError>
70 where
71 T: serde::de::Deserialize<'a>,
72 {
73 from_cbor(item.data()).map_err(|err| BlockSerializerError::Deserialize(*item.cid(), err.into()))
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use crate::library::block_serializer::BlockSerializer;
81 use serde::Serialize;
82
83 #[derive(Debug, Serialize)]
84 struct Test {
85 hello: String,
86 }
87
88 #[test]
89 fn should_serialize() {
90 let test = Test { hello: "world".to_owned() };
91 let block = BlockSerializer::default().serialize(&test).unwrap();
92 assert_eq!(block.cid().to_string(), "bafyr4iahzl6dyblh5gjfk5lo46xkkfk7fvxhyot4636rdglz3n5tayegd4");
93 assert_eq!(block.data(), [161, 101, 104, 101, 108, 108, 111, 101, 119, 111, 114, 108, 100]);
94 }
95}