pedronauck_data_parser/
compression_strategies.rs1pub use async_compression::{
2 tokio::write as compression_encoders_and_decoders,
3 Level as CompressionLevel,
4};
5use tokio::io::AsyncWriteExt;
6
7use crate::CompressionError;
8
9mod private {
12 pub trait Sealed {}
13}
14
15#[async_trait::async_trait]
28pub trait CompressionStrategy: private::Sealed + Sync + Send {
29 fn name(&self) -> &'static str;
31
32 async fn compress(
42 &self,
43 uncompressed: &[u8],
44 ) -> Result<Vec<u8>, CompressionError>;
45
46 async fn decompress(
56 &self,
57 compressed: &[u8],
58 ) -> Result<Vec<u8>, CompressionError>;
59}
60
61macro_rules! define_compression_strategy {
72 ($name:ident, $compression_type:ident, $compression_level:ty) => {
73 impl private::Sealed for $name {}
74
75 #[async_trait::async_trait]
76 impl CompressionStrategy for $name {
77 fn name(&self) -> &'static str {
78 stringify!($name)
79 }
80
81 async fn compress(&self, uncompressed: &[u8]) -> Result<Vec<u8>, CompressionError> {
82 paste::paste! {
83 let mut encoder = compression_encoders_and_decoders::[<$compression_type Encoder>]::with_quality(Vec::new(), $compression_level);
84 encoder
85 .write_all(uncompressed)
86 .await
87 .map_err(|e| CompressionError::[<$compression_type>](e))?;
88 encoder
89 .shutdown()
90 .await
91 .map_err(|e| CompressionError::[<$compression_type>](e))?;
92 Ok(encoder.into_inner())
93 }
94 }
95
96 async fn decompress(&self, compressed: &[u8]) -> Result<Vec<u8>, CompressionError> {
97 paste::paste! {
98 let mut decoder = compression_encoders_and_decoders::[<$compression_type Decoder>]::new(Vec::new());
99 decoder
100 .write_all(compressed)
101 .await
102 .map_err(|e| CompressionError::[<$compression_type>](e))?;
103 decoder
104 .shutdown()
105 .await
106 .map_err(|e| CompressionError::[<$compression_type>](e))?;
107 Ok(decoder.into_inner())
108 }
109 }
110 }
111 };
112}
113
114#[cfg(feature = "zlib")]
115#[derive(Clone)]
116pub struct ZlibCompressionStrategy;
117#[cfg(feature = "zlib")]
118define_compression_strategy!(
119 ZlibCompressionStrategy,
120 Zlib,
121 CompressionLevel::Fastest
122);
123
124#[cfg(feature = "gzip")]
125#[derive(Clone)]
126pub struct GzipCompressionStrategy;
127#[cfg(feature = "gzip")]
128define_compression_strategy!(
129 GzipCompressionStrategy,
130 Gzip,
131 CompressionLevel::Fastest
132);
133
134#[cfg(feature = "brotli")]
135#[derive(Clone)]
136pub struct BrotliCompressionStrategy;
137#[cfg(feature = "brotli")]
138define_compression_strategy!(
139 BrotliCompressionStrategy,
140 Brotli,
141 CompressionLevel::Fastest
142);
143
144#[cfg(feature = "bzip2")]
145#[derive(Clone)]
146pub struct BzCompressionStrategy;
147#[cfg(feature = "bzip2")]
148define_compression_strategy!(
149 BzCompressionStrategy,
150 Bz,
151 CompressionLevel::Fastest
152);
153
154#[cfg(feature = "lzma")]
155#[derive(Clone)]
156pub struct LzmaCompressionStrategy;
157#[cfg(feature = "lzma")]
158define_compression_strategy!(
159 LzmaCompressionStrategy,
160 Lzma,
161 CompressionLevel::Fastest
162);
163
164#[cfg(feature = "deflate")]
165#[derive(Clone)]
166pub struct DeflateCompressionStrategy;
167#[cfg(feature = "deflate")]
168define_compression_strategy!(
169 DeflateCompressionStrategy,
170 Deflate,
171 CompressionLevel::Fastest
172);
173
174#[cfg(feature = "zstd")]
175#[derive(Clone)]
176pub struct ZstdCompressionStrategy;
177#[cfg(feature = "zstd")]
178define_compression_strategy!(
179 ZstdCompressionStrategy,
180 Zstd,
181 CompressionLevel::Fastest
182);
183
184use std::sync::Arc;
185
186lazy_static::lazy_static! {
187 pub static ref DEFAULT_COMPRESSION_STRATEGY: Arc<dyn CompressionStrategy> = Arc::new(ZstdCompressionStrategy);
188}
189
190lazy_static::lazy_static! {
191 pub static ref ALL_COMPRESSION_STRATEGIES: Vec<Arc<dyn CompressionStrategy>> = vec![
192 #[cfg(feature = "zlib")]
193 Arc::new(ZlibCompressionStrategy),
194 #[cfg(feature = "gzip")]
195 Arc::new(GzipCompressionStrategy),
196 #[cfg(feature = "brotli")]
197 Arc::new(BrotliCompressionStrategy),
198 #[cfg(feature = "bzip2")]
199 Arc::new(BzCompressionStrategy),
200 #[cfg(feature = "lzma")]
201 Arc::new(LzmaCompressionStrategy),
202 #[cfg(feature = "deflate")]
203 Arc::new(DeflateCompressionStrategy),
204 #[cfg(feature = "zstd")]
205 Arc::new(ZstdCompressionStrategy),
206 ];
207}