#[cfg(feature = "compression")]
use crate::compressor::Quality;
use thiserror::Error;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum WindowEncoding {
Standard,
Large,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct Window {
bits: u8,
encoding: WindowEncoding,
}
impl Window {
pub const MIN_BITS: u8 = 10;
pub const MAX_STANDARD_BITS: u8 = 24;
pub const MAX_LARGE_BITS: u8 = 62;
pub const DEFAULT: Self = Self {
bits: 22,
encoding: WindowEncoding::Standard,
};
pub const fn standard(bits: u8) -> Result<Self, ConfigError> {
if bits < Self::MIN_BITS || bits > Self::MAX_STANDARD_BITS {
return Err(ConfigError::StandardWindow { requested: bits });
}
Ok(Self {
bits,
encoding: WindowEncoding::Standard,
})
}
pub const fn large(bits: u8) -> Result<Self, ConfigError> {
if bits < Self::MIN_BITS || bits > Self::MAX_LARGE_BITS {
return Err(ConfigError::LargeWindow { requested: bits });
}
Ok(Self {
bits,
encoding: WindowEncoding::Large,
})
}
#[must_use]
pub const fn bits(self) -> u8 {
self.bits
}
#[must_use]
pub const fn encoding(self) -> WindowEncoding {
self.encoding
}
}
impl Default for Window {
fn default() -> Self {
Self::DEFAULT
}
}
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum ConfigError {
#[error("quality {requested} is outside the 0..=11 the format defines")]
#[cfg(feature = "compression")]
Quality {
requested: u8,
},
#[error("an ordinary window of {requested} bits is outside the 10..=24 RFC 7932 expresses")]
StandardWindow {
requested: u8,
},
#[error("a large window of {requested} bits is outside the 10..=62 RFC 9841 expresses")]
LargeWindow {
requested: u8,
},
#[error("a block size of {requested} bits is outside the 16..=24 the encoder accepts")]
#[cfg(feature = "compression")]
BlockBits {
requested: u8,
},
#[error("{requested} distance postfix bits is more than the 3 RFC 7932 allows")]
#[cfg(feature = "compression")]
DistancePostfixBits {
requested: u8,
},
#[error("{requested} direct distance codes is more than the 120 RFC 7932 allows")]
#[cfg(feature = "compression")]
DirectDistanceCodes {
requested: u16,
},
#[error(
"{direct_codes} direct distance codes is not a whole number of \
1 << {postfix_bits} groups the header can hold"
)]
#[cfg(feature = "compression")]
MisalignedDistanceCodes {
postfix_bits: u8,
direct_codes: u16,
},
#[error("quality {} cannot carry a large window", quality.get())]
#[cfg(feature = "compression")]
LargeWindowUnsupportedForQuality {
quality: Quality,
},
}