mca/
compression.rs

1use std::io::{Read, Write};
2
3use crate::McaError;
4
5/// Compression types used in chunks
6///
7/// **`GZip` & `Custom` is unsupported currently**
8#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
9#[repr(u8)]
10pub enum CompressionType {
11    GZip = 1,
12    Zlib = 2,
13    Uncompressed = 3,
14    LZ4 = 4,
15    Custom = 127,
16}
17
18impl From<u8> for CompressionType {
19    fn from(value: u8) -> Self {
20        CompressionType::from_u8(value)
21    }
22}
23
24impl From<CompressionType> for u8 {
25    fn from(value: CompressionType) -> Self {
26        value.to_u8()
27    }
28}
29
30impl CompressionType {
31    pub fn from_u8(value: u8) -> CompressionType {
32        match value {
33            1 => CompressionType::GZip,
34            2 => CompressionType::Zlib,
35            3 => CompressionType::Uncompressed,
36            4 => CompressionType::LZ4,
37            127 => CompressionType::Custom,
38            _ => panic!("Invalid compression type: {}", value),
39        }
40    }
41
42    pub fn to_u8(&self) -> u8 {
43        match self {
44            CompressionType::GZip => 1,
45            CompressionType::Zlib => 2,
46            CompressionType::Uncompressed => 3,
47            CompressionType::LZ4 => 4,
48            CompressionType::Custom => 127,
49        }
50    }
51
52    /// Takes in a byte slice and uses the current compression type to **compress** the data
53    pub fn compress(&self, data: &[u8]) -> Result<Vec<u8>, McaError> {
54        match self {
55            CompressionType::Zlib => Ok(miniz_oxide::deflate::compress_to_vec_zlib(&data, 4)),
56            CompressionType::Uncompressed => Ok(data.to_vec()),
57            CompressionType::LZ4 => Ok({
58                let mut buf: Vec<u8> = Vec::new();
59                lz4_java_wrc::Lz4BlockOutput::new(&mut buf).write_all(&data)?;
60                buf
61            }),
62            CompressionType::GZip => unimplemented!("This is unused in practice and if you somehow need this, make an issue on github and i'll add it <3"),
63            CompressionType::Custom => unimplemented!("Haven't implemented this and i don't personally need this but make an issue on github and i'll fix it <3"),
64        }
65    }
66
67    /// Takes in a byte slice and uses the current compression type to **decompress** the data
68    pub fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, McaError> {
69        match self {
70            CompressionType::Zlib => Ok(miniz_oxide::inflate::decompress_to_vec_zlib(
71                &data,
72            )?),
73            CompressionType::Uncompressed => Ok(data.to_vec()),
74            CompressionType::LZ4 => Ok({
75                let mut buf: Vec<u8> = Vec::new();
76                lz4_java_wrc::Lz4BlockInput::new(&data[..]).read_to_end(&mut buf)?;
77                buf
78            }),
79            CompressionType::GZip => unimplemented!("This is unused in practice and if you somehow need this, make an issue on github and i'll add it <3"),
80            CompressionType::Custom => unimplemented!("Haven't implemented this and i don't personally need this but make an issue on github and i'll fix it <3")
81        }
82    }
83}