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}