ipld_block_builder/
codec.rs

1#[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
17/// Encoder trait.
18pub trait Encoder {
19    /// Ipld codec.
20    type Codec: Codec;
21    /// Hasher.
22    type Hash: Multihasher<Code>;
23
24    /// Encodes the value into a block.
25    fn encode<T: Encode<Self::Codec>>(&self, value: &T) -> Result<Block>;
26}
27
28/// Decoder trait.
29pub trait Decoder {
30    /// Ipld codec.
31    type Codec: Codec;
32
33    /// Decodes the block into a value.
34    fn decode<T: Decode<Self::Codec>>(&self, cid: &Cid, data: &[u8]) -> Result<T>;
35}
36
37/// Ipld decoder trait.
38pub trait IpldDecoder {
39    /// Decodes the block into `Ipld`.
40    fn decode_ipld(&self, cid: &Cid, data: &[u8]) -> Result<Ipld>;
41}
42
43/// Marker trait for encrypted encoders.
44pub trait Encrypted {}
45
46/// Generic ipld codec.
47#[derive(Clone, Default)]
48pub struct GenericCodec<C, H> {
49    _marker: PhantomData<(C, H)>,
50}
51
52impl<C, H> GenericCodec<C, H> {
53    /// Create a new generic codec.
54    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/// Generic encrypted codec.
85#[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    /// Creates a new generic strobe codec.
95    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> {}