use core::{convert::Infallible, fmt};
mod sealed {
use crate::error::UnpackError;
pub trait Sealed {}
impl<T, U, V> Sealed for Result<T, UnpackError<U, V>> {}
}
pub trait UnpackErrorExt<T, U, V>: sealed::Sealed + Sized {
fn map_packable_err<W>(self, f: impl Fn(U) -> W) -> Result<T, UnpackError<W, V>>;
fn coerce<W>(self) -> Result<T, UnpackError<W, V>>
where
U: Into<W>,
{
self.map_packable_err(U::into)
}
}
impl<T, U, V> UnpackErrorExt<T, U, V> for Result<T, UnpackError<U, V>> {
fn map_packable_err<W>(self, f: impl Fn(U) -> W) -> Result<T, UnpackError<W, V>> {
self.map_err(|err| match err {
UnpackError::Packable(err) => UnpackError::Packable(f(err)),
UnpackError::Unpacker(err) => UnpackError::Unpacker(err),
})
}
}
#[derive(Debug)]
pub enum UnpackError<T, U> {
Packable(T),
Unpacker(U),
}
impl<T, U> UnpackError<T, U> {
pub fn from_packable(err: impl Into<T>) -> Self {
Self::Packable(err.into())
}
}
impl<T, U> From<U> for UnpackError<T, U> {
fn from(err: U) -> Self {
Self::Unpacker(err)
}
}
impl<U> UnpackError<Infallible, U> {
pub fn into_unpacker_err(self) -> U {
match self {
Self::Packable(err) => match err {},
Self::Unpacker(err) => err,
}
}
}
impl<T> UnpackError<T, Infallible> {
pub fn into_packable_err(self) -> T {
match self {
Self::Packable(err) => err,
Self::Unpacker(err) => match err {},
}
}
}
impl<T, U> fmt::Display for UnpackError<T, U>
where
T: fmt::Display,
U: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Packable(err) => write!(f, "packable error while unpacking: {}", err),
Self::Unpacker(err) => write!(f, "unpacker error while unpacking: {}", err),
}
}
}
#[cfg(feature = "std")]
impl<T, U> std::error::Error for UnpackError<T, U>
where
T: std::error::Error,
U: std::error::Error,
{
}
impl From<UnpackError<Infallible, Infallible>> for Infallible {
fn from(val: UnpackError<Infallible, Infallible>) -> Self {
let (UnpackError::Packable(err) | UnpackError::Unpacker(err)) = val;
match err {}
}
}
#[derive(Debug)]
pub struct UnknownTagError<T>(pub T);
#[cfg(feature = "std")]
impl<T> std::error::Error for UnknownTagError<T> where T: fmt::Display + fmt::Debug {}
impl<T> From<Infallible> for UnknownTagError<T> {
fn from(err: Infallible) -> Self {
match err {}
}
}
impl<T: fmt::Display> fmt::Display for UnknownTagError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "unknown tag value {}", self.0)
}
}
#[derive(Debug)]
pub struct UnexpectedEOF {
pub required: usize,
pub had: usize,
}
#[cfg(feature = "std")]
impl std::error::Error for UnexpectedEOF {}
impl fmt::Display for UnexpectedEOF {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "not enough bytes, required {} but had {}", self.required, self.had)
}
}