1use std::io::Error;
2use std::io::Read;
3use std::io::Write;
4
5use bzip2::read::BzDecoder;
6use deko::write::AnyEncoder;
7use deko::write::Compression as DekoCompression;
8use deko::Format;
9use flate2::read::ZlibDecoder;
10use xz::read::XzDecoder;
11
12#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
14pub enum Compression {
15 None,
19 #[default]
21 Gzip,
22 Bzip2,
24 Xz,
26}
27
28impl Compression {
29 pub fn as_str(self) -> &'static str {
31 match self {
32 Self::None => OCTET_STREAM_MIME_TYPE,
33 Self::Gzip => GZIP_MIME_TYPE,
34 Self::Bzip2 => BZIP2_MIME_TYPE,
35 Self::Xz => XZ_MIME_TYPE,
36 }
37 }
38
39 pub fn encoder<W: Write>(self, writer: W) -> Result<AnyEncoder<W>, Error> {
41 match self {
42 Self::None => AnyEncoder::new(writer, Format::Verbatim, DekoCompression::Best),
43 Self::Gzip => AnyEncoder::new(writer, Format::Zlib, DekoCompression::Best),
44 Self::Bzip2 => AnyEncoder::new(writer, Format::Bz, DekoCompression::Best),
45 Self::Xz => AnyEncoder::new(writer, Format::Xz, DekoCompression::Best),
46 }
47 }
48
49 pub fn decoder<R: Read>(self, reader: R) -> XarDecoder<R> {
51 match self {
52 Self::None => XarDecoder::OctetStream(reader),
53 Self::Gzip => XarDecoder::Gzip(ZlibDecoder::new(reader)),
54 Self::Bzip2 => XarDecoder::Bzip2(BzDecoder::new(reader)),
55 Self::Xz => XarDecoder::Xz(XzDecoder::new(reader)),
56 }
57 }
58}
59
60impl From<&str> for Compression {
61 fn from(s: &str) -> Self {
62 match s {
63 GZIP_MIME_TYPE | ZLIB_MIME_TYPE => Self::Gzip,
64 BZIP2_MIME_TYPE => Self::Bzip2,
65 XZ_MIME_TYPE => Self::Xz,
66 _ => Self::None,
67 }
68 }
69}
70
71pub enum XarDecoder<R: Read> {
73 OctetStream(R),
75 Gzip(ZlibDecoder<R>),
77 Bzip2(BzDecoder<R>),
79 Xz(XzDecoder<R>),
81}
82
83impl<R: Read> Read for XarDecoder<R> {
84 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
85 match self {
86 Self::OctetStream(r) => r.read(buf),
87 Self::Gzip(r) => r.read(buf),
88 Self::Bzip2(r) => r.read(buf),
89 Self::Xz(r) => r.read(buf),
90 }
91 }
92
93 }
95
96const OCTET_STREAM_MIME_TYPE: &str = "application/octet-stream";
97const GZIP_MIME_TYPE: &str = "application/x-gzip";
98const BZIP2_MIME_TYPE: &str = "application/x-bzip2";
99const ZLIB_MIME_TYPE: &str = "application/zlib";
100const XZ_MIME_TYPE: &str = "application/x-xz";