use std::error::Error as StdError;
use std::fmt;
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
#[derive(Debug)]
pub(super) enum ErrorKind {
#[cfg(feature = "rt-tokio")]
OffsetLargerThanFileSize,
#[cfg(feature = "rt-tokio")]
LengthLargerThanFileSizeMinusReadOffset,
IoError(IoError),
StreamingError(Box<dyn StdError + Send + Sync + 'static>),
}
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl Error {
pub(super) fn streaming(err: impl Into<Box<dyn StdError + Send + Sync + 'static>>) -> Self {
ErrorKind::StreamingError(err.into()).into()
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Self {
Self { kind }
}
}
impl From<IoError> for Error {
fn from(err: IoError) -> Self {
ErrorKind::IoError(err).into()
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
#[cfg(feature = "rt-tokio")]
ErrorKind::OffsetLargerThanFileSize => write!(
f,
"offset must be less than or equal to file size but was greater than"
),
#[cfg(feature = "rt-tokio")]
ErrorKind::LengthLargerThanFileSizeMinusReadOffset => write!(
f,
"`Length::Exact` was larger than file size minus read offset"
),
ErrorKind::IoError(_) => write!(f, "IO error"),
ErrorKind::StreamingError(_) => write!(f, "streaming error"),
}
}
}
impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match &self.kind {
ErrorKind::IoError(err) => Some(err as _),
ErrorKind::StreamingError(err) => Some(err.as_ref() as _),
#[cfg(feature = "rt-tokio")]
ErrorKind::OffsetLargerThanFileSize
| ErrorKind::LengthLargerThanFileSizeMinusReadOffset => None,
}
}
}
impl From<Error> for IoError {
fn from(err: Error) -> Self {
IoError::new(IoErrorKind::Other, err)
}
}