use zstd_safe::{ErrorCode, get_error_name, zstd_sys::ZSTD_ErrorCode};
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
kind: Kind,
}
impl Error {
pub fn is_number_conversion_failed(&self) -> bool {
matches!(self.kind, Kind::NumberConversionFailed(_))
}
pub(crate) fn offset_out_of_range() -> Self {
Self {
kind: Kind::OffsetOutOfRange,
}
}
pub fn is_offset_out_of_range(&self) -> bool {
matches!(self.kind, Kind::OffsetOutOfRange)
}
pub(crate) fn frame_index_too_large() -> Self {
Self {
kind: Kind::FrameIndexTooLarge,
}
}
pub fn is_frame_index_too_large(&self) -> bool {
matches!(self.kind, Kind::FrameIndexTooLarge)
}
pub(crate) fn zstd(code: ZSTD_ErrorCode) -> Self {
let wrapped = 0_usize.wrapping_sub(code as usize);
Self {
kind: Kind::Zstd(wrapped),
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn is_io(&self) -> bool {
matches!(self.kind, Kind::IO(_))
}
pub fn is_zstd(&self) -> bool {
matches!(self.kind, Kind::Zstd(_))
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match &self.kind {
Kind::NumberConversionFailed(err) => write!(f, "number conversion failed: {err}"),
Kind::OffsetOutOfRange => f.write_str("offset out of range"),
Kind::FrameIndexTooLarge => f.write_str("frame index too large"),
#[cfg(feature = "std")]
Kind::IO(err) => write!(f, "io error: {err}"),
Kind::Zstd(code) => f.write_str(get_error_name(*code)),
}
}
}
impl core::error::Error for Error {}
impl From<core::num::TryFromIntError> for Error {
fn from(value: core::num::TryFromIntError) -> Self {
Self {
kind: Kind::NumberConversionFailed(value),
}
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Self {
kind: Kind::IO(value),
}
}
}
impl From<ErrorCode> for Error {
fn from(value: ErrorCode) -> Self {
Self {
kind: Kind::Zstd(value),
}
}
}
enum Kind {
NumberConversionFailed(core::num::TryFromIntError),
OffsetOutOfRange,
FrameIndexTooLarge,
#[cfg(feature = "std")]
IO(std::io::Error),
Zstd(ErrorCode),
}
impl core::fmt::Debug for Kind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::NumberConversionFailed(arg0) => {
f.debug_tuple("NumberConversionFailed").field(arg0).finish()
}
Self::OffsetOutOfRange => write!(f, "OffsetOutOfRange"),
Self::FrameIndexTooLarge => write!(f, "FrameIndexTooLarge"),
#[cfg(feature = "std")]
Self::IO(arg0) => f.debug_tuple("IO").field(arg0).finish(),
Self::Zstd(c) => write!(f, "{}; code {}", zstd_safe::get_error_name(*c), c),
}
}
}