1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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,
{
}
#[allow(clippy::from_over_into)]
impl Into<Infallible> for UnpackError<Infallible, Infallible> {
fn into(self) -> Infallible {
let (Self::Packable(err) | Self::Unpacker(err)) = self;
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)
}
}