reth_db_api/
scale.rs

1use crate::{
2    table::{Compress, Decompress},
3    DatabaseError,
4};
5use alloy_primitives::U256;
6
7mod sealed {
8    pub trait Sealed {}
9}
10
11/// Marker trait type to restrict the [`Compress`] and [`Decompress`] with scale to chosen types.
12pub trait ScaleValue: sealed::Sealed {}
13
14impl<T> Compress for T
15where
16    T: ScaleValue + parity_scale_codec::Encode + Sync + Send + std::fmt::Debug,
17{
18    type Compressed = Vec<u8>;
19
20    fn compress(self) -> Self::Compressed {
21        parity_scale_codec::Encode::encode(&self)
22    }
23
24    fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(&self, buf: &mut B) {
25        parity_scale_codec::Encode::encode_to(&self, OutputCompat::wrap_mut(buf));
26    }
27}
28
29impl<T> Decompress for T
30where
31    T: ScaleValue + parity_scale_codec::Decode + Sync + Send + std::fmt::Debug,
32{
33    fn decompress(mut value: &[u8]) -> Result<T, DatabaseError> {
34        parity_scale_codec::Decode::decode(&mut value).map_err(|_| DatabaseError::Decode)
35    }
36}
37
38/// Implements compression for SCALE type.
39macro_rules! impl_compression_for_scale {
40    ($($name:tt),+) => {
41        $(
42            impl ScaleValue for $name {}
43            impl sealed::Sealed for $name {}
44        )+
45    };
46}
47
48impl ScaleValue for Vec<u8> {}
49impl sealed::Sealed for Vec<u8> {}
50
51impl_compression_for_scale!(U256);
52impl_compression_for_scale!(u8, u32, u16, u64);
53
54#[repr(transparent)]
55struct OutputCompat<B>(B);
56
57impl<B> OutputCompat<B> {
58    fn wrap_mut(buf: &mut B) -> &mut Self {
59        unsafe { std::mem::transmute(buf) }
60    }
61}
62
63impl<B: bytes::BufMut> parity_scale_codec::Output for OutputCompat<B> {
64    fn write(&mut self, bytes: &[u8]) {
65        self.0.put_slice(bytes);
66    }
67
68    fn push_byte(&mut self, byte: u8) {
69        self.0.put_u8(byte);
70    }
71}