ipld_block_builder/
codec.rs1#[cfg(feature = "crypto")]
2use crate::crypto::Key;
3use libipld::block::Block;
4use libipld::cid::Cid;
5use libipld::codec::{Codec, Decode, Encode};
6#[cfg(feature = "crypto")]
7use libipld::error::Error;
8use libipld::error::Result;
9use libipld::ipld::Ipld;
10use libipld::multihash::{Code, Multihasher};
11#[cfg(feature = "crypto")]
12use libipld::raw::RawCodec;
13use std::marker::PhantomData;
14#[cfg(feature = "crypto")]
15use std::sync::Arc;
16
17pub trait Encoder {
19 type Codec: Codec;
21 type Hash: Multihasher<Code>;
23
24 fn encode<T: Encode<Self::Codec>>(&self, value: &T) -> Result<Block>;
26}
27
28pub trait Decoder {
30 type Codec: Codec;
32
33 fn decode<T: Decode<Self::Codec>>(&self, cid: &Cid, data: &[u8]) -> Result<T>;
35}
36
37pub trait IpldDecoder {
39 fn decode_ipld(&self, cid: &Cid, data: &[u8]) -> Result<Ipld>;
41}
42
43pub trait Encrypted {}
45
46#[derive(Clone, Default)]
48pub struct GenericCodec<C, H> {
49 _marker: PhantomData<(C, H)>,
50}
51
52impl<C, H> GenericCodec<C, H> {
53 pub fn new() -> Self {
55 Self {
56 _marker: PhantomData,
57 }
58 }
59}
60
61impl<C: Codec, H: Multihasher<Code>> Encoder for GenericCodec<C, H> {
62 type Codec = C;
63 type Hash = H;
64
65 fn encode<T: Encode<C>>(&self, value: &T) -> Result<Block> {
66 libipld::block::encode::<C, H, T>(value)
67 }
68}
69
70impl<C: Codec, H> Decoder for GenericCodec<C, H> {
71 type Codec = C;
72
73 fn decode<T: Decode<C>>(&self, cid: &Cid, data: &[u8]) -> Result<T> {
74 libipld::block::decode::<C, T>(cid, data)
75 }
76}
77
78impl<C, H> IpldDecoder for GenericCodec<C, H> {
79 fn decode_ipld(&self, cid: &Cid, data: &[u8]) -> Result<Ipld> {
80 libipld::block::decode_ipld(cid, data)
81 }
82}
83
84#[cfg(feature = "crypto")]
86#[derive(Clone)]
87pub struct GenericStrobeCodec<C, H> {
88 _marker: PhantomData<(C, H)>,
89 key: Arc<Key>,
90}
91
92#[cfg(feature = "crypto")]
93impl<C, H> GenericStrobeCodec<C, H> {
94 pub fn new(key: Key) -> Self {
96 Self {
97 _marker: PhantomData,
98 key: Arc::new(key),
99 }
100 }
101}
102
103#[cfg(feature = "crypto")]
104impl<C: Codec, H: Multihasher<Code>> Encoder for GenericStrobeCodec<C, H> {
105 type Codec = C;
106 type Hash = H;
107
108 fn encode<T: Encode<C>>(&self, value: &T) -> Result<Block> {
109 let data = C::encode(value).map_err(|e| Error::CodecError(Box::new(e)))?;
110 let ct = crate::crypto::encrypt(&self.key, C::CODE, &data)
111 .map_err(|e| Error::CodecError(Box::new(e)))?;
112 libipld::block::encode::<RawCodec, H, _>(&ct)
113 }
114}
115
116#[cfg(feature = "crypto")]
117impl<C: Codec, H> Decoder for GenericStrobeCodec<C, H> {
118 type Codec = C;
119
120 fn decode<T: Decode<C>>(&self, cid: &Cid, data: &[u8]) -> Result<T> {
121 let ct = libipld::block::decode::<RawCodec, Box<[u8]>>(cid, data)?;
122 let (codec, data) =
123 crate::crypto::decrypt(&self.key, ct).map_err(|e| Error::CodecError(Box::new(e)))?;
124 libipld::block::raw_decode::<C, T>(codec, &data)
125 }
126}
127
128#[cfg(feature = "crypto")]
129impl<C, H> IpldDecoder for GenericStrobeCodec<C, H> {
130 fn decode_ipld(&self, cid: &Cid, data: &[u8]) -> Result<Ipld> {
131 let ct = libipld::block::decode::<RawCodec, Box<[u8]>>(cid, data)?;
132 let (codec, data) =
133 crate::crypto::decrypt(&self.key, ct).map_err(|e| Error::CodecError(Box::new(e)))?;
134 libipld::block::raw_decode_ipld(codec, &data)
135 }
136}
137
138#[cfg(feature = "crypto")]
139impl<C, H> Encrypted for GenericStrobeCodec<C, H> {}