1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
use std::io::{Read, Write};


pub mod raw;
#[cfg(feature = "bzip")]
pub mod bzip;
#[cfg(feature = "gzip")]
pub mod gzip;
#[cfg(feature = "lz")]
pub mod lz;
#[cfg(feature = "xz")]
pub mod xz;


pub trait Compression {
    fn decoder<'a, R: Read + 'a>(&self, r: R) -> Box<Read + 'a>;

    fn encoder<'a, W: Write + 'a>(&self, w: W) -> Box<Write + 'a>;
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type")]
pub enum CompressionType {
    Raw(raw::RawCompression),
    #[cfg(feature = "bzip")]
    Bzip2(bzip::Bzip2Compression),
    #[cfg(feature = "gzip")]
    Gzip(gzip::GzipCompression),
    #[cfg(feature = "lz")]
    Lz4(lz::Lz4Compression),
    #[cfg(feature = "xz")]
    Xz(xz::XzCompression),
}

// impl CompressionType {
//     pub fn get_reader<'a, R: Read + 'a>(&self) -> Box<Compression<'a, R>> {
//         #[allow(unreachable_patterns)] // Ignore the default case.
//         match *self {
//             CompressionType::Raw => Box::new(raw::RawCompression),

//             #[cfg(feature = "bzip")]
//             CompressionType::Bzip2(ref params) =>
//                 Box::new(bzip::Bzip2Compression::new(params)),

//             #[cfg(feature = "gzip")]
//             CompressionType::Gzip(ref params) =>
//                 Box::new(gzip::GzipCompression::new(params)),

//             #[cfg(feature = "xz")]
//             CompressionType::Xz(ref params) =>
//                 Box::new(xz::XzCompression::new(params)),

//             #[cfg(feature = "lz")]
//             CompressionType::Lz4(ref params) =>
//                 Box::new(lz::Lz4Compression::new(params)),

//             // Default case to panic if the requested compression feature is not
//             // enabled.
//             _ => unimplemented!(),
//         }
//     }
// }

impl Compression for CompressionType {
    fn decoder<'a, R: Read + 'a>(&self, r: R) -> Box<Read + 'a> {
        #[allow(unreachable_patterns)] // Ignore the default case.
        match *self {
            CompressionType::Raw(ref c) => c.decoder(r),

            #[cfg(feature = "bzip")]
            CompressionType::Bzip2(ref c) => c.decoder(r),

            #[cfg(feature = "gzip")]
            CompressionType::Gzip(ref c) => c.decoder(r),

            #[cfg(feature = "xz")]
            CompressionType::Xz(ref c) => c.decoder(r),

            #[cfg(feature = "lz")]
            CompressionType::Lz4(ref c) => c.decoder(r),

            // Default case to panic if the requested compression feature is not
            // enabled.
            _ => unimplemented!(),
        }
    }

    fn encoder<'a, W: Write + 'a>(&self, w: W) -> Box<Write + 'a> {
        #[allow(unreachable_patterns)] // Ignore the default case.
        match *self {
            CompressionType::Raw(ref c) => c.encoder(w),

            #[cfg(feature = "bzip")]
            CompressionType::Bzip2(ref c) => c.encoder(w),

            #[cfg(feature = "gzip")]
            CompressionType::Gzip(ref c) => c.encoder(w),

            #[cfg(feature = "xz")]
            CompressionType::Xz(ref c) => c.encoder(w),

            #[cfg(feature = "lz")]
            CompressionType::Lz4(ref c) => c.encoder(w),

            // Default case to panic if the requested compression feature is not
            // enabled.
            _ => unimplemented!(),
        }
    }
}