building_blocks_storage/
compression.rs

1mod compressed_bincode;
2
3#[cfg(feature = "lz4")]
4mod lz4_compression;
5#[cfg(feature = "snap")]
6mod snappy_compression;
7
8pub use compressed_bincode::BincodeCompression;
9
10#[cfg(feature = "lz4")]
11pub use lz4_compression::Lz4;
12#[cfg(feature = "snap")]
13pub use snappy_compression::Snappy;
14
15use serde::{Deserialize, Serialize};
16
17/// An algorithm for:
18///     1. compressing a specific type `Data` into type `Compressed`
19///     2. decompressing `Compressed` back into `Data`
20pub trait Compression: Sized {
21    type Data;
22    type CompressedData;
23
24    fn compress(&self, data: &Self::Data) -> Compressed<Self>;
25    fn decompress(compressed: &Self::CompressedData) -> Self::Data;
26}
27
28pub trait FromBytesCompression<B> {
29    fn from_bytes_compression(bytes_compression: B) -> Self;
30}
31
32/// A value compressed with compression algorithm `A`.
33#[derive(Clone, Deserialize, Serialize)]
34pub struct Compressed<A>
35where
36    A: Compression,
37{
38    pub compressed_data: A::CompressedData,
39    marker: std::marker::PhantomData<A>,
40}
41
42impl<T, A> Compressed<A>
43where
44    A: Compression<CompressedData = T>,
45{
46    pub fn new(compressed_data: A::CompressedData) -> Self {
47        Self {
48            compressed_data,
49            marker: Default::default(),
50        }
51    }
52
53    pub fn decompress(&self) -> A::Data {
54        A::decompress(&self.compressed_data)
55    }
56
57    pub fn take(self) -> A::CompressedData {
58        self.compressed_data
59    }
60}
61
62/// A compression algorithm that acts directly on a slice of bytes.
63pub trait BytesCompression {
64    fn compress_bytes(&self, bytes: &[u8], compressed_bytes: impl std::io::Write);
65    fn decompress_bytes(compressed_bytes: &[u8], bytes: &mut impl std::io::Write);
66}
67
68/// A value that is either compressed or decompressed.
69pub enum MaybeCompressed<D, C> {
70    Decompressed(D),
71    Compressed(C),
72}
73
74impl<A: Compression> MaybeCompressed<A::Data, Compressed<A>> {
75    pub fn into_decompressed(self) -> A::Data {
76        match self {
77            MaybeCompressed::Compressed(c) => c.decompress(),
78            MaybeCompressed::Decompressed(d) => d,
79        }
80    }
81
82    pub fn unwrap_decompressed(self) -> A::Data {
83        match self {
84            MaybeCompressed::Compressed(_) => panic!("Must be decompressed"),
85            MaybeCompressed::Decompressed(d) => d,
86        }
87    }
88}