tibba_util/compression.rs
1// Copyright 2025 Tree xie.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use super::Error;
16use lz4_flex::block::{compress_prepend_size, decompress_size_prepended};
17
18// Custom Result type using the crate's Error type
19type Result<T> = std::result::Result<T, Error>;
20
21/// An enum to represent supported compression algorithms and their parameters.
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum Algorithm {
24 /// LZ4 algorithm.
25 Lz4,
26 /// Zstandard (zstd) algorithm, can specify compression level.
27 Zstd(i32),
28}
29
30/// Provide a default implementation for Algorithm, for easy use.
31impl Default for Algorithm {
32 fn default() -> Self {
33 // Default to using zstd's default compression level, as it usually has a good balance between compression ratio and speed.
34 Algorithm::Zstd(zstd::DEFAULT_COMPRESSION_LEVEL)
35 }
36}
37
38/// Compress data using the specified algorithm.
39///
40/// # Arguments
41/// * `data` - Original data bytes.
42/// * `algorithm` - The compression algorithm to use (`Algorithm::Lz4` or `Algorithm::Zstd(level)`).
43///
44/// # Returns
45/// * `Result<Vec<u8>>` - Compressed data or error.
46pub fn compress(data: &[u8], algorithm: Algorithm) -> Result<Vec<u8>> {
47 match algorithm {
48 Algorithm::Lz4 => {
49 // LZ4's compression function does not return an error, so we wrap it in Ok.
50 Ok(compress_prepend_size(data))
51 }
52 Algorithm::Zstd(level) => {
53 // Optimization: use zstd::encode_all, code is more concise.
54 zstd::encode_all(data, level).map_err(|e| Error::Zstd { source: e })
55 }
56 }
57}
58
59/// Decompress data using the specified algorithm.
60///
61/// # Arguments
62/// * `data` - Compressed data bytes.
63/// * `algorithm` - The compression algorithm used.
64///
65/// # Returns
66/// * `Result<Vec<u8>>` - Decompressed data or error.
67pub fn decompress(data: &[u8], algorithm: Algorithm) -> Result<Vec<u8>> {
68 match algorithm {
69 Algorithm::Lz4 => {
70 decompress_size_prepended(data).map_err(|e| Error::Lz4Decompress { source: e })
71 }
72 // Decompression does not require compression level, so ignore the level parameter of Zstd.
73 Algorithm::Zstd(_) => {
74 // Optimization: use zstd::decode_all, code is more concise.
75 zstd::decode_all(data).map_err(|e| Error::Zstd { source: e })
76 }
77 }
78}