Skip to main content

ordinary_utils/
compression.rs

1// Copyright (C) 2026 Ordinary Labs, LLC.
2//
3// SPDX-License-Identifier: AGPL-3.0-only
4
5use async_compression::Level;
6use async_compression::tokio::write::{BrotliEncoder, GzipEncoder, ZlibEncoder, ZstdEncoder};
7use bytes::Bytes;
8use hashbrown::HashMap;
9use tokio::io::AsyncWriteExt;
10
11pub async fn get_compressed(payload: &[u8], compression: &str, level: Option<Level>) -> Bytes {
12    match compression {
13        "gzip" => {
14            let mut encoder = GzipEncoder::new(Vec::new());
15            if let Err(err) = encoder.write_all(payload.as_ref()).await {
16                tracing::error!(%err);
17            }
18            if let Err(err) = encoder.shutdown().await {
19                tracing::error!(%err);
20            }
21            Bytes::copy_from_slice(encoder.into_inner().as_slice())
22        }
23        "zstd" => {
24            let mut encoder =
25                ZstdEncoder::with_quality(Vec::new(), level.unwrap_or(Level::Precise(17)));
26            if let Err(err) = encoder.write_all(payload).await {
27                tracing::error!(%err);
28            }
29            if let Err(err) = encoder.shutdown().await {
30                tracing::error!(%err);
31            }
32            Bytes::copy_from_slice(encoder.into_inner().as_slice())
33        }
34        "br" => {
35            let mut encoder = BrotliEncoder::new(Vec::new());
36            if let Err(err) = encoder.write_all(payload).await {
37                tracing::error!(%err);
38            }
39            if let Err(err) = encoder.shutdown().await {
40                tracing::error!(%err);
41            }
42            Bytes::copy_from_slice(encoder.into_inner().as_slice())
43        }
44        "deflate" => {
45            let mut encoder = ZlibEncoder::new(Vec::new());
46            if let Err(err) = encoder.write_all(payload).await {
47                tracing::error!(%err);
48            }
49            if let Err(err) = encoder.shutdown().await {
50                tracing::error!(%err);
51            }
52            Bytes::copy_from_slice(encoder.into_inner().as_slice())
53        }
54        _ => Bytes::copy_from_slice(payload),
55    }
56}
57
58pub async fn get_compressed_all(payload: &[u8]) -> HashMap<String, Bytes> {
59    let mut compression_map = HashMap::with_capacity(4);
60
61    for compression in ["gzip", "zstd", "br", "deflate"] {
62        compression_map.insert(
63            compression.to_owned(),
64            get_compressed(payload, compression, None).await,
65        );
66    }
67
68    compression_map
69}