use std::fmt;
use num_enum::{FromPrimitive, IntoPrimitive};
use crate::compressor::{self, Compressor};
use crate::decompressor::{self, Decompressor};
use crate::error::Error;
#[cfg(feature = "brotli")]
const HAS_BROTLI: bool = true;
#[cfg(not(feature = "brotli"))]
const HAS_BROTLI: bool = false;
#[cfg(feature = "deflate")]
const HAS_DEFLATE: bool = true;
#[cfg(not(feature = "deflate"))]
const HAS_DEFLATE: bool = false;
#[cfg(feature = "fastlz")]
const HAS_FASTLZ: bool = true;
#[cfg(not(feature = "fastlz"))]
const HAS_FASTLZ: bool = false;
#[cfg(feature = "gzip")]
const HAS_GZIP: bool = true;
#[cfg(not(feature = "gzip"))]
const HAS_GZIP: bool = false;
#[cfg(feature = "zstd")]
const HAS_ZSTD: bool = true;
#[cfg(not(feature = "zstd"))]
const HAS_ZSTD: bool = false;
#[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, IntoPrimitive, PartialEq)]
#[repr(u32)]
pub enum CompressionMode {
#[allow(missing_docs)]
FastLZ = 0,
#[allow(missing_docs)]
Deflate,
#[allow(missing_docs)]
Zstd,
#[allow(missing_docs)]
Gzip,
#[allow(missing_docs)]
Brotli,
#[num_enum(catch_all)]
Unknown(u32),
}
impl fmt::Display for CompressionMode {
#[cfg_attr(test, coverage(off))]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:#?}")
}
}
#[cfg(feature = "cli")]
impl clap::ValueEnum for CompressionMode {
fn value_variants<'a>() -> &'a [Self] {
&[
CompressionMode::Brotli,
CompressionMode::Deflate,
CompressionMode::FastLZ,
CompressionMode::Gzip,
CompressionMode::Zstd,
]
}
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
match self {
CompressionMode::Brotli => Some("brotli".into()),
CompressionMode::Deflate => Some("deflate".into()),
CompressionMode::FastLZ => Some("fastlz".into()),
CompressionMode::Gzip => Some("gzip".into()),
CompressionMode::Zstd => Some("zstd".into()),
CompressionMode::Unknown(_) => None,
}
}
}
impl CompressionMode {
#[cfg_attr(test, coverage(off))]
#[must_use]
pub fn is_enabled(&self) -> bool {
match self {
Self::FastLZ => HAS_FASTLZ,
Self::Deflate => HAS_DEFLATE,
Self::Zstd => HAS_ZSTD,
Self::Gzip => HAS_GZIP,
Self::Brotli => HAS_BROTLI,
Self::Unknown(_) => false,
}
}
#[cfg_attr(test, coverage(off))]
pub fn get_compressor(&self) -> Result<Box<dyn Compressor>, Error> {
match self {
#[cfg(feature = "fastlz")]
Self::FastLZ => Ok(Box::new(compressor::fastlz::FastLZCompressor::default())),
#[cfg(feature = "deflate")]
Self::Deflate => Ok(Box::new(compressor::deflate::DeflateCompressor::default())),
#[cfg(feature = "zstd")]
Self::Zstd => Ok(Box::new(compressor::zstd::ZstdCompressor::default())),
#[cfg(feature = "gzip")]
Self::Gzip => Ok(Box::new(compressor::gzip::GzipCompressor::default())),
#[cfg(feature = "brotli")]
Self::Brotli => Ok(Box::new(compressor::brotli::BrotliCompressor::default())),
Self::Unknown(c) => Err(Error::UnknownMode(*c)),
#[allow(unreachable_patterns)]
mode => Err(Error::NoCompressor(*mode)),
}
}
#[cfg_attr(test, coverage(off))]
pub fn get_decompressor(&self) -> Result<Box<dyn Decompressor>, Error> {
match self {
#[cfg(feature = "fastlz")]
Self::FastLZ => Ok(Box::new(decompressor::fastlz::FastLZDecompressor::default())),
#[cfg(feature = "deflate")]
Self::Deflate => Ok(Box::new(
decompressor::deflate::DeflateDecompressor::default(),
)),
#[cfg(feature = "zstd")]
Self::Zstd => Ok(Box::new(decompressor::zstd::ZstdDecompressor::default())),
#[cfg(feature = "gzip")]
Self::Gzip => Ok(Box::new(decompressor::gzip::GzipDecompressor::default())),
#[cfg(feature = "brotli")]
Self::Brotli => Ok(Box::new(decompressor::brotli::BrotliDecompressor::default())),
Self::Unknown(c) => Err(Error::UnknownMode(*c)),
#[allow(unreachable_patterns)]
mode => Err(Error::NoDecompressor(*mode)),
}
}
}