1use crate::tags::CompressionMethod;
2use std::io::{self, Write};
3
4mod deflate;
5mod lzw;
6mod packbits;
7mod uncompressed;
8
9pub use self::deflate::{Deflate, DeflateLevel};
10pub use self::lzw::Lzw;
11pub use self::packbits::Packbits;
12pub use self::uncompressed::Uncompressed;
13
14/// An algorithm used for compression
15pub trait CompressionAlgorithm {
16 /// The algorithm writes data directly into the writer.
17 /// It returns the total number of bytes written.
18 fn write_to<W: Write>(&mut self, writer: &mut W, bytes: &[u8]) -> Result<u64, io::Error>;
19}
20
21/// An algorithm used for compression with associated enums and optional configurations.
22pub trait Compression: CompressionAlgorithm {
23 /// The corresponding tag to the algorithm.
24 const COMPRESSION_METHOD: CompressionMethod;
25
26 /// Method to optain a type that can store each variant of comression algorithm.
27 fn get_algorithm(&self) -> Compressor;
28}
29
30/// An enum to store each compression algorithm.
31pub enum Compressor {
32 Uncompressed(Uncompressed),
33 Lzw(Lzw),
34 Deflate(Deflate),
35 Packbits(Packbits),
36}
37
38impl Default for Compressor {
39 /// The default compression strategy does not apply any compression.
40 fn default() -> Self {
41 Compressor::Uncompressed(Uncompressed)
42 }
43}
44
45impl CompressionAlgorithm for Compressor {
46 fn write_to<W: Write>(&mut self, writer: &mut W, bytes: &[u8]) -> Result<u64, io::Error> {
47 match self {
48 Compressor::Uncompressed(algorithm: &mut Uncompressed) => algorithm.write_to(writer, bytes),
49 Compressor::Lzw(algorithm: &mut Lzw) => algorithm.write_to(writer, bytes),
50 Compressor::Deflate(algorithm: &mut Deflate) => algorithm.write_to(writer, bytes),
51 Compressor::Packbits(algorithm: &mut Packbits) => algorithm.write_to(writer, bytes),
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 pub const TEST_DATA: &[u8] = b"This is a string for checking various compression algorithms.";
59}
60