1#![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#[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}