1
2use std::borrow::Cow;
5use std::io::ErrorKind;
6pub use std::io::Error as IoError;
7pub use std::io::Result as IoResult;
8use std::convert::TryFrom;
9use std::error;
10use std::fmt;
11use std::num::TryFromIntError;
12
13
14pub type Result<T> = std::result::Result<T, Error>;
18
19pub type UnitResult = Result<()>;
21
22
23#[derive(Debug)]
27pub enum Error {
28
29 Aborted, NotSupported(Cow<'static, str>),
39
40 Invalid(Cow<'static, str>),
43
44 Io(IoError),
47}
48
49
50impl Error {
51
52 pub(crate) fn invalid(message: impl Into<Cow<'static, str>>) -> Self {
54 Error::Invalid(message.into())
55 }
56
57 pub(crate) fn unsupported(message: impl Into<Cow<'static, str>>) -> Self {
59 Error::NotSupported(message.into())
60 }
61}
62
63impl From<IoError> for Error {
65 fn from(error: IoError) -> Self {
66 if error.kind() == ErrorKind::UnexpectedEof {
67 Error::invalid("reference to missing bytes")
68 }
69 else {
70 Error::Io(error)
71 }
72 }
73}
74
75impl From<TryFromIntError> for Error {
77 fn from(_: TryFromIntError) -> Self {
78 Error::invalid("invalid size")
79 }
80}
81
82impl error::Error for Error {
83 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
84 match *self {
85 Error::Io(ref err) => Some(err),
86 _ => None,
87 }
88 }
89}
90
91impl fmt::Display for Error {
92 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
93 match self {
94 Error::Io(err) => err.fmt(formatter),
95 Error::NotSupported(message) => write!(formatter, "not supported: {}", message),
96 Error::Invalid(message) => write!(formatter, "invalid: {}", message),
97 Error::Aborted => write!(formatter, "cancelled"),
98 }
99 }
100}
101
102#[inline]
104pub(crate) fn i32_to_usize(value: i32, error_message: &'static str) -> Result<usize> {
105 usize::try_from(value).map_err(|_| {
106 if value < 0 { Error::invalid(error_message) }
107 else { Error::unsupported(error_message) }
108 })
109}
110
111#[inline]
113pub(crate) fn usize_to_u32(value: usize, error_message: &'static str) -> Result<u32> {
114 u32::try_from(value).map_err(|_| Error::invalid(error_message))
115}
116
117#[inline]
119pub(crate) fn usize_to_u16(value: usize, error_message: &'static str) -> Result<u16> {
120 u16::try_from(value).map_err(|_| Error::invalid(error_message))
121}
122
123#[inline]
125pub(crate) fn u64_to_usize(value: u64, error_message: &'static str) -> Result<usize> {
126 usize::try_from(value).map_err(|_| Error::unsupported(error_message))
127}
128
129#[inline]
131pub(crate) fn u32_to_usize(value: u32, error_message: &'static str) -> Result<usize> {
132 usize::try_from(value).map_err(|_| Error::unsupported(error_message))
133}
134
135#[inline]
137pub(crate) fn usize_to_i32(value: usize, error_message: &'static str) -> Result<i32> {
138 i32::try_from(value).map_err(|_| Error::invalid(error_message))
139}
140
141#[inline]
143pub(crate) fn usize_to_u64(value: usize, error_message: &'static str) -> Result<u64> {
144 u64::try_from(value).map_err(|_| Error::invalid(error_message))
145}