1use crate::{
2 codec::{
3 Codec,
4 Decode,
5 Encode,
6 UnsupportedCodec,
7 },
8 ipld::Ipld,
9};
10
11use sp_cid::Cid;
12use sp_multihash::{
13 Code,
14 MultihashDigest,
15};
16
17use core::convert::TryFrom;
18
19pub mod decode;
20pub mod encode;
21
22#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
24pub struct DagCborCodec;
25
26impl Codec for DagCborCodec {}
27
28impl From<DagCborCodec> for u64 {
29 fn from(_: DagCborCodec) -> Self { 0x71 }
30}
31
32impl TryFrom<u64> for DagCborCodec {
33 type Error = UnsupportedCodec;
34
35 fn try_from(_: u64) -> core::result::Result<Self, Self::Error> { Ok(Self) }
36}
37
38pub trait DagCbor: Encode<DagCborCodec> + Decode<DagCborCodec> {}
41
42impl<T: Encode<DagCborCodec> + Decode<DagCborCodec>> DagCbor for T {}
43
44pub fn cid(x: &Ipld) -> Cid {
49 Cid::new_v1(
50 0x71,
51 Code::Blake2b256
52 .digest(DagCborCodec.encode(x).unwrap().into_inner().as_ref()),
53 )
54}
55
56#[cfg(test)]
57pub mod tests {
58 use super::*;
59 use crate::ipld::*;
60 use bytecursor::ByteCursor;
61 use quickcheck::{
62 quickcheck,
63 Arbitrary,
64 Gen,
65 };
66
67 use alloc::collections::btree_map::BTreeMap;
68
69 fn encode_decode_id<T: DagCbor + PartialEq<T> + Clone>(value: T) -> bool {
70 let mut bc = ByteCursor::new(Vec::new());
71 match Encode::encode(&value, DagCborCodec, &mut bc) {
72 Ok(()) => {
73 bc.set_position(0);
74 match Decode::decode(DagCborCodec, &mut bc) {
75 Ok(new_value) => return value == new_value,
76 Err(e) => println!("Error occurred during decoding: {}", e),
77 }
78 }
79 Err(e) => println!("Error occurred during encoding: {}", e),
80 }
81 false
82 }
83
84 #[quickcheck]
85 pub fn edid_null() -> bool { encode_decode_id(Ipld::Null) }
86
87 #[quickcheck]
88 pub fn edid_bool(x: bool) -> bool { encode_decode_id(Ipld::Bool(x)) }
89
90 #[quickcheck]
91 pub fn edid_integer(x: i64) -> bool {
92 encode_decode_id(Ipld::Integer(x as i128))
93 }
94
95 #[quickcheck]
96 pub fn edid_bytes(x: Vec<u8>) -> bool { encode_decode_id(Ipld::Bytes(x)) }
97
98 #[quickcheck]
99 pub fn edid_string(x: String) -> bool { encode_decode_id(Ipld::String(x)) }
100
101 #[quickcheck]
103 pub fn edid_list(x: Vec<Ipld>) -> bool { encode_decode_id(Ipld::List(x)) }
104
105 #[quickcheck]
106 pub fn edid_string_map(x: BTreeMap<String, Ipld>) -> bool {
107 encode_decode_id(Ipld::StringMap(x))
108 }
109
110 #[derive(Debug, Clone)]
111 pub struct ACid(pub Cid);
112
113 impl Arbitrary for ACid {
114 fn arbitrary(g: &mut Gen) -> Self {
115 ACid(crate::ipld::tests::arbitrary_cid(g))
116 }
117 }
118
119 #[quickcheck]
120 pub fn edid_link(x: ACid) -> bool { encode_decode_id(Ipld::Link(x.0)) }
121}