summavy/store/
decompressors.rs1use std::io;
2
3use serde::{Deserialize, Serialize};
4
5use super::Compressor;
6
7pub trait StoreCompressor {
8 fn compress(&self, uncompressed: &[u8], compressed: &mut Vec<u8>) -> io::Result<()>;
9 fn decompress(&self, compressed: &[u8], decompressed: &mut Vec<u8>) -> io::Result<()>;
10 fn get_compressor_id() -> u8;
11}
12
13#[derive(Clone, Debug, Copy, PartialEq, Eq, Serialize, Deserialize)]
15pub enum Decompressor {
16 None,
18 Lz4,
20 Brotli,
22 Snappy,
24 Zstd,
26}
27
28impl From<Compressor> for Decompressor {
29 fn from(compressor: Compressor) -> Self {
30 match compressor {
31 Compressor::None => Decompressor::None,
32 Compressor::Lz4 => Decompressor::Lz4,
33 Compressor::Brotli => Decompressor::Brotli,
34 Compressor::Snappy => Decompressor::Snappy,
35 Compressor::Zstd(_) => Decompressor::Zstd,
36 }
37 }
38}
39
40impl Decompressor {
41 pub(crate) fn from_id(id: u8) -> Decompressor {
42 match id {
43 0 => Decompressor::None,
44 1 => Decompressor::Lz4,
45 2 => Decompressor::Brotli,
46 3 => Decompressor::Snappy,
47 4 => Decompressor::Zstd,
48 _ => panic!("unknown compressor id {:?}", id),
49 }
50 }
51
52 pub(crate) fn get_id(&self) -> u8 {
53 match self {
54 Self::None => 0,
55 Self::Lz4 => 1,
56 Self::Brotli => 2,
57 Self::Snappy => 3,
58 Self::Zstd => 4,
59 }
60 }
61
62 pub(crate) fn decompress(&self, compressed_block: &[u8]) -> io::Result<Vec<u8>> {
63 let mut decompressed_block = vec![];
64 self.decompress_into(compressed_block, &mut decompressed_block)?;
65 Ok(decompressed_block)
66 }
67
68 #[inline]
69 pub(crate) fn decompress_into(
70 &self,
71 compressed: &[u8],
72 decompressed: &mut Vec<u8>,
73 ) -> io::Result<()> {
74 match self {
75 Self::None => {
76 decompressed.clear();
77 decompressed.extend_from_slice(compressed);
78 Ok(())
79 }
80 Self::Lz4 => {
81 #[cfg(feature = "lz4-compression")]
82 {
83 super::compression_lz4_block::decompress(compressed, decompressed)
84 }
85 #[cfg(not(feature = "lz4-compression"))]
86 {
87 panic!("lz4-compression feature flag not activated");
88 }
89 }
90 Self::Brotli => {
91 #[cfg(feature = "brotli-compression")]
92 {
93 super::compression_brotli::decompress(compressed, decompressed)
94 }
95 #[cfg(not(feature = "brotli-compression"))]
96 {
97 panic!("brotli-compression feature flag not activated");
98 }
99 }
100 Self::Snappy => {
101 #[cfg(feature = "snappy-compression")]
102 {
103 super::compression_snap::decompress(compressed, decompressed)
104 }
105 #[cfg(not(feature = "snappy-compression"))]
106 {
107 panic!("snappy-compression feature flag not activated");
108 }
109 }
110 Self::Zstd => {
111 #[cfg(feature = "zstd-compression")]
112 {
113 super::compression_zstd_block::decompress(compressed, decompressed)
114 }
115 #[cfg(not(feature = "zstd-compression"))]
116 {
117 panic!("zstd-compression feature flag not activated");
118 }
119 }
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 use crate::store::Compressor;
128
129 #[test]
130 fn compressor_decompressor_id_test() {
131 assert_eq!(Decompressor::from(Compressor::None), Decompressor::None);
132 assert_eq!(Decompressor::from(Compressor::Lz4), Decompressor::Lz4);
133 assert_eq!(Decompressor::from(Compressor::Brotli), Decompressor::Brotli);
134 assert_eq!(Decompressor::from(Compressor::Snappy), Decompressor::Snappy);
135 assert_eq!(
136 Decompressor::from(Compressor::Zstd(Default::default())),
137 Decompressor::Zstd
138 );
139 }
140}