genio/error.rs
1//! Error types and various operations on them.
2
3use void::Void;
4use void;
5use ::core::fmt;
6
7/// Specifies an error that happened during I/O operation. This enables one to compose read and
8/// write errors into single type.
9///
10/// This is different than `std::io::Error`!
11#[derive(Debug)]
12pub enum IOError<R, W> {
13 /// Read operation failed.
14 Read(R),
15 /// Write operation failed.
16 Write(W),
17}
18
19impl<R, W> IOError<R, W> {
20 /// Merges the variants into common type.
21 pub fn merge<E>(e: IOError<R, W>) -> E where R: Into<E>, W: Into<E> {
22 match e {
23 IOError::Read(e) => e.into(),
24 IOError::Write(e) => e.into(),
25 }
26 }
27
28 /// Get `IOError` containing references to errors.
29 pub fn as_ref(&self) -> IOError<&R, &W> {
30 match *self {
31 IOError::Read(ref f) => IOError::Read(f),
32 IOError::Write(ref s) => IOError::Write(s),
33 }
34 }
35
36 /// Get `IOError` containing mutable references to errors.
37 pub fn as_ref_mut(&mut self) -> IOError<&mut R, &mut W> {
38 match *self {
39 IOError::Read(ref mut f) => IOError::Read(f),
40 IOError::Write(ref mut s) => IOError::Write(s),
41 }
42 }
43}
44
45/// Error that might occur when reading exact amount of bytes.
46#[derive(Debug)]
47pub enum ReadExactError<E> {
48 /// Low-level error happened.
49 Other(E),
50
51 /// Reader reached end unexpectedly.
52 ///
53 /// Usually EOF, closed connection, etc.
54 UnexpectedEnd,
55}
56
57impl<E> From<E> for ReadExactError<E> {
58 fn from(e: E) -> Self {
59 ReadExactError::Other(e)
60 }
61}
62
63/// Error returned when chained readers fail. It allows inspecting which reader failed, keeping
64/// it's own error type. For simplicity it can be also merged, if the two errors are convertible to
65/// resulting error.
66#[derive(Debug)]
67pub enum ChainError<F, S> {
68 /// First reader failed.
69 First(F),
70 /// Second reader failed.
71 Second(S),
72}
73
74impl<F, S> ChainError<F, S> {
75 /// If the two errors can be converted to same type, they can be easily merged by this method.
76 /// This simply performs the conversion.
77 pub fn merge<E>(self) -> E where F: Into<E>, S: Into<E> {
78 match self {
79 ChainError::First(f) => f.into(),
80 ChainError::Second(s) => s.into(),
81 }
82 }
83
84 /// Get `ChainError` containing references to errors.
85 pub fn as_ref(&self) -> ChainError<&F, &S> {
86 match *self {
87 ChainError::First(ref f) => ChainError::First(f),
88 ChainError::Second(ref s) => ChainError::Second(s),
89 }
90 }
91
92 /// Get ChainError containing mutable references to errors.
93 pub fn as_ref_mut(&mut self) -> ChainError<&mut F, &mut S> {
94 match *self {
95 ChainError::First(ref mut f) => ChainError::First(f),
96 ChainError::Second(ref mut s) => ChainError::Second(s),
97 }
98 }
99}
100
101/// This error type indicates that operation might fail in restartible manner. The most obvious
102/// case is `EINTR` returned from syscalls when a signal is delivered while doing `read`.
103#[derive(Debug)]
104pub enum IntrError<E> {
105 /// The error wasn't interruption.
106 Other(E),
107 /// An operation was interrupted. This variant means that operation can be retried and it will
108 /// likely succeed.
109 Interrupted,
110}
111
112/// Trait for custom error types that can also represent interruption.
113pub trait IntoIntrError {
114 /// Type representing other error (non-interrupt).
115 type NonIntr;
116
117 /// Performs the conversion.
118 fn into_intr_error(self) -> IntrError<Self::NonIntr>;
119}
120
121impl<E> IntoIntrError for IntrError<E> {
122 type NonIntr = E;
123
124 fn into_intr_error(self) -> IntrError<Self::NonIntr> {
125 self
126 }
127}
128
129impl<T> From<Void> for IntrError<T> {
130 fn from(e: Void) -> Self {
131 void::unreachable(e)
132 }
133}
134
135// Should this be implemented?
136/*
137impl IntoIntrError for Void {
138 type NonIntr = Void;
139
140 fn into_intr_error(self) -> IntrError<Self::NonIntr> {
141 self.into()
142 }
143}
144*/
145
146/// Error that might occur when interacting with buf reader.
147#[derive(Debug)]
148pub enum BufError<B, E> {
149 /// The underlying stream reached the end.
150 End,
151 /// Buffer itself failed.
152 BufferErr(B),
153 /// The underlying stream failed.
154 OtherErr(E),
155}
156
157/// Error that might occur when doing operation on `ExtendFromReader`
158#[derive(Debug)]
159pub enum ExtendError<R, E> {
160 /// Reader failed
161 ReadErr(R),
162 /// The type being extended failed.
163 ExtendErr(E),
164}
165
166/// Error indicating that provided buffer was too small
167#[derive(Debug)]
168pub struct BufferOverflow;
169
170impl fmt::Display for BufferOverflow {
171 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172 write!(f, "provided buffer was too small")
173 }
174}