1#![deny(missing_docs)]
3#![deny(warnings)]
4
5use core::convert::TryFrom;
6use libipld_core::cid::Cid;
7use libipld_core::codec::{Codec, Decode, Encode, References};
8use libipld_core::error::{Result, UnsupportedCodec};
9use libipld_core::ipld::Ipld;
10pub use serde_json::Error;
12use std::io::{Read, Seek, Write};
13
14mod codec;
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
18pub struct DagJsonCodec;
19
20impl Codec for DagJsonCodec {}
21
22impl From<DagJsonCodec> for u64 {
23    fn from(_: DagJsonCodec) -> Self {
24        0x0129
25    }
26}
27
28impl TryFrom<u64> for DagJsonCodec {
29    type Error = UnsupportedCodec;
30
31    fn try_from(_: u64) -> core::result::Result<Self, Self::Error> {
32        Ok(Self)
33    }
34}
35
36impl Encode<DagJsonCodec> for Ipld {
37    fn encode<W: Write>(&self, _: DagJsonCodec, w: &mut W) -> Result<()> {
38        Ok(codec::encode(self, w)?)
39    }
40}
41
42impl Decode<DagJsonCodec> for Ipld {
43    fn decode<R: Read + Seek>(_: DagJsonCodec, r: &mut R) -> Result<Self> {
44        Ok(codec::decode(r)?)
45    }
46}
47
48impl References<DagJsonCodec> for Ipld {
49    fn references<R: Read + Seek, E: Extend<Cid>>(
50        c: DagJsonCodec,
51        r: &mut R,
52        set: &mut E,
53    ) -> Result<()> {
54        Ipld::decode(c, r)?.references(set);
55        Ok(())
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use libipld_core::cid::Cid;
63    use libipld_core::multihash::{Code, MultihashDigest};
64    use std::collections::BTreeMap;
65
66    #[test]
67    fn encode_struct() {
68        let digest = Code::Blake3_256.digest(&b"block"[..]);
69        let cid = Cid::new_v1(0x55, digest);
70
71        let mut map = BTreeMap::new();
74        map.insert("name".to_string(), Ipld::String("Hello World!".to_string()));
75        map.insert("details".to_string(), Ipld::Link(cid));
76        let contact = Ipld::Map(map);
77
78        let contact_encoded = DagJsonCodec.encode(&contact).unwrap();
79        println!("encoded: {:02x?}", contact_encoded);
80        println!(
81            "encoded string {}",
82            std::str::from_utf8(&contact_encoded).unwrap()
83        );
84
85        assert_eq!(
86            std::str::from_utf8(&contact_encoded).unwrap(),
87            format!(r#"{{"details":{{"/":"{}"}},"name":"Hello World!"}}"#, cid)
88        );
89
90        let contact_decoded: Ipld = DagJsonCodec.decode(&contact_encoded).unwrap();
91        assert_eq!(contact_decoded, contact);
92    }
93}