lurk_ipld_pb/
lib.rs

1//! Protobuf codec.
2#![deny(missing_docs)]
3#![deny(warnings)]
4#![allow(clippy::derive_partial_eq_without_eq)]
5
6pub use crate::codec::{PbLink, PbNode};
7use core::convert::{TryFrom, TryInto};
8use lurk_ipld_core::cid::Cid;
9use lurk_ipld_core::codec::{Codec, Decode, Encode, References};
10use lurk_ipld_core::error::{Result, UnsupportedCodec};
11use lurk_ipld_core::ipld::Ipld;
12use prost::bytes::Bytes;
13use std::io::{Read, Seek, Write};
14
15mod codec;
16mod dag_pb;
17
18/// Protobuf codec.
19#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
20pub struct DagPbCodec;
21
22impl Codec for DagPbCodec {}
23
24impl From<DagPbCodec> for u64 {
25    fn from(_: DagPbCodec) -> Self {
26        0x70
27    }
28}
29
30impl TryFrom<u64> for DagPbCodec {
31    type Error = UnsupportedCodec;
32
33    fn try_from(_: u64) -> core::result::Result<Self, Self::Error> {
34        Ok(Self)
35    }
36}
37
38impl Encode<DagPbCodec> for Ipld {
39    fn encode<W: Write>(&self, _: DagPbCodec, w: &mut W) -> Result<()> {
40        let pb_node: PbNode = self.try_into()?;
41        let bytes = pb_node.into_bytes();
42        w.write_all(&bytes)?;
43        Ok(())
44    }
45}
46
47impl Decode<DagPbCodec> for Ipld {
48    fn decode<R: Read + Seek>(_: DagPbCodec, r: &mut R) -> Result<Self> {
49        let mut bytes = Vec::new();
50        r.read_to_end(&mut bytes)?;
51        Ok(PbNode::from_bytes(Bytes::from(bytes))?.into())
52    }
53}
54
55impl References<DagPbCodec> for Ipld {
56    fn references<R: Read + Seek, E: Extend<Cid>>(
57        _: DagPbCodec,
58        r: &mut R,
59        set: &mut E,
60    ) -> Result<()> {
61        let mut bytes = Vec::new();
62        r.read_to_end(&mut bytes)?;
63        PbNode::links(Bytes::from(bytes), set)
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use lurk_ipld_core::cid::Cid;
71    use lurk_ipld_core::multihash::{Code, MultihashDigest};
72    use std::collections::BTreeMap;
73
74    #[test]
75    fn test_encode_decode() {
76        let digest = Code::Blake3_256.digest(&b"cid"[..]);
77        let cid = Cid::new_v1(0x55, digest);
78        let mut pb_link = BTreeMap::<String, Ipld>::new();
79        pb_link.insert("Hash".to_string(), cid.into());
80        pb_link.insert("Name".to_string(), "block".to_string().into());
81        pb_link.insert("Tsize".to_string(), 13.into());
82
83        let links: Vec<Ipld> = vec![pb_link.into()];
84        let mut pb_node = BTreeMap::<String, Ipld>::new();
85        pb_node.insert("Data".to_string(), b"Here is some data\n".to_vec().into());
86        pb_node.insert("Links".to_string(), links.into());
87        let data: Ipld = pb_node.into();
88
89        let bytes = DagPbCodec.encode(&data).unwrap();
90        let data2 = DagPbCodec.decode(&bytes).unwrap();
91        assert_eq!(data, data2);
92    }
93}