@@ -99,6 +99,10 @@ pub enum ErrorKind {
99
99
///
100
100
/// [`InvalidInput`]: ErrorKind::InvalidInput
101
101
InvalidData ,
102
+ /// The underlying storage (typically, a filesystem) is full.
103
+ ///
104
+ /// This does not include out of quota errors.
105
+ StorageFull ,
102
106
/// The I/O operation's timeout expired, causing it to be canceled.
103
107
TimedOut ,
104
108
/// This operation was interrupted.
@@ -109,6 +113,13 @@ pub enum ErrorKind {
109
113
///
110
114
/// This means that the operation can never succeed.
111
115
Unsupported ,
116
+ /// An error returned when an operation could not be completed because an
117
+ /// "end of file" was reached prematurely.
118
+ ///
119
+ /// This typically means that an operation could only succeed if it read a
120
+ /// particular number of bytes but only a smaller number of bytes could be
121
+ /// read.
122
+ UnexpectedEof ,
112
123
/// An operation could not be completed, because it failed
113
124
/// to allocate enough memory.
114
125
OutOfMemory ,
@@ -133,9 +144,11 @@ impl From<ErrorKind> for std::io::ErrorKind {
133
144
ErrorKind :: AlreadyExists => std:: io:: ErrorKind :: AlreadyExists ,
134
145
ErrorKind :: InvalidInput => std:: io:: ErrorKind :: InvalidInput ,
135
146
ErrorKind :: InvalidData => std:: io:: ErrorKind :: InvalidData ,
147
+ ErrorKind :: StorageFull => std:: io:: ErrorKind :: StorageFull ,
136
148
ErrorKind :: TimedOut => std:: io:: ErrorKind :: TimedOut ,
137
149
ErrorKind :: Interrupted => std:: io:: ErrorKind :: Interrupted ,
138
150
ErrorKind :: Unsupported => std:: io:: ErrorKind :: Unsupported ,
151
+ ErrorKind :: UnexpectedEof => std:: io:: ErrorKind :: UnexpectedEof ,
139
152
ErrorKind :: OutOfMemory => std:: io:: ErrorKind :: OutOfMemory ,
140
153
_ => std:: io:: ErrorKind :: Other ,
141
154
}
@@ -159,9 +172,11 @@ impl From<std::io::ErrorKind> for ErrorKind {
159
172
std:: io:: ErrorKind :: AlreadyExists => ErrorKind :: AlreadyExists ,
160
173
std:: io:: ErrorKind :: InvalidInput => ErrorKind :: InvalidInput ,
161
174
std:: io:: ErrorKind :: InvalidData => ErrorKind :: InvalidData ,
175
+ std:: io:: ErrorKind :: StorageFull => ErrorKind :: StorageFull ,
162
176
std:: io:: ErrorKind :: TimedOut => ErrorKind :: TimedOut ,
163
177
std:: io:: ErrorKind :: Interrupted => ErrorKind :: Interrupted ,
164
178
std:: io:: ErrorKind :: Unsupported => ErrorKind :: Unsupported ,
179
+ std:: io:: ErrorKind :: UnexpectedEof => ErrorKind :: UnexpectedEof ,
165
180
std:: io:: ErrorKind :: OutOfMemory => ErrorKind :: OutOfMemory ,
166
181
_ => ErrorKind :: Other ,
167
182
}
@@ -172,17 +187,11 @@ impl From<std::io::ErrorKind> for ErrorKind {
172
187
///
173
188
/// This trait allows generic code to do limited inspecting of errors,
174
189
/// to react differently to different kinds.
175
- pub trait Error : core:: error:: Error {
190
+ pub trait Error : core:: error:: Error + From < ErrorKind > {
176
191
/// Get the kind of this error.
177
192
fn kind ( & self ) -> ErrorKind ;
178
193
}
179
194
180
- impl Error for core:: convert:: Infallible {
181
- fn kind ( & self ) -> ErrorKind {
182
- match * self { }
183
- }
184
- }
185
-
186
195
impl Error for ErrorKind {
187
196
fn kind ( & self ) -> ErrorKind {
188
197
* self
@@ -205,6 +214,14 @@ impl Error for std::io::Error {
205
214
}
206
215
}
207
216
217
+ #[ cfg( feature = "std" ) ]
218
+ #[ cfg_attr( docsrs, doc( cfg( feature = "std" ) ) ) ]
219
+ impl From < ErrorKimd > for std:: io:: Error {
220
+ fn from ( value : ErrorKimd ) -> Self {
221
+ std:: io:: ErrorKind :: from ( value) . into ( )
222
+ }
223
+ }
224
+
208
225
/// Base trait for all IO traits, defining the error type.
209
226
///
210
227
/// All IO operations of all traits return the error defined in this trait.
@@ -223,44 +240,6 @@ impl<T: ?Sized + ErrorType> ErrorType for &mut T {
223
240
type Error = T :: Error ;
224
241
}
225
242
226
- /// Error returned by [`Read::read_exact`]
227
- #[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
228
- #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
229
- pub enum ReadExactError < E > {
230
- /// An EOF error was encountered before reading the exact amount of requested bytes.
231
- UnexpectedEof ,
232
- /// Error returned by the inner Read.
233
- Other ( E ) ,
234
- }
235
-
236
- impl < E > From < E > for ReadExactError < E > {
237
- fn from ( err : E ) -> Self {
238
- Self :: Other ( err)
239
- }
240
- }
241
-
242
- #[ cfg( feature = "std" ) ]
243
- #[ cfg_attr( docsrs, doc( cfg( feature = "std" ) ) ) ]
244
- impl From < ReadExactError < std:: io:: Error > > for std:: io:: Error {
245
- fn from ( err : ReadExactError < std:: io:: Error > ) -> Self {
246
- match err {
247
- ReadExactError :: UnexpectedEof => std:: io:: Error :: new (
248
- std:: io:: ErrorKind :: UnexpectedEof ,
249
- "UnexpectedEof" . to_owned ( ) ,
250
- ) ,
251
- ReadExactError :: Other ( e) => std:: io:: Error :: new ( e. kind ( ) , format ! ( "{e:?}" ) ) ,
252
- }
253
- }
254
- }
255
-
256
- impl < E : fmt:: Debug > fmt:: Display for ReadExactError < E > {
257
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
258
- write ! ( f, "{self:?}" )
259
- }
260
- }
261
-
262
- impl < E : fmt:: Debug > core:: error:: Error for ReadExactError < E > { }
263
-
264
243
/// Errors that could be returned by `Write` on `&mut [u8]`.
265
244
#[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
266
245
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
@@ -326,6 +305,15 @@ pub trait Read: ErrorType {
326
305
///
327
306
/// If `buf.len() == 0`, `read` returns without blocking, with either `Ok(0)` or an error.
328
307
/// The `Ok(0)` doesn't indicate EOF, unlike when called with a non-empty buffer.
308
+ ///
309
+ /// # Errors
310
+ ///
311
+ /// If this function encounters any form of I/O or other error, an error
312
+ /// variant will be returned. If an error is returned then it must be
313
+ /// guaranteed that no bytes were read.
314
+ ///
315
+ /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the read
316
+ /// operation should be retried if there is nothing else to do.
329
317
fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > ;
330
318
331
319
/// Read the exact number of bytes required to fill `buf`.
@@ -336,18 +324,31 @@ pub trait Read: ErrorType {
336
324
/// If you are using [`ReadReady`] to avoid blocking, you should not use this function.
337
325
/// `ReadReady::read_ready()` returning true only guarantees the first call to `read()` will
338
326
/// not block, so this function may still block in subsequent calls.
339
- fn read_exact ( & mut self , mut buf : & mut [ u8 ] ) -> Result < ( ) , ReadExactError < Self :: Error > > {
327
+ ////
328
+ /// /// # Errors
329
+ ///
330
+ /// If this function encounters an "end of file" before completely filling
331
+ /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
332
+ /// The contents of `buf` are unspecified in this case.
333
+ ///
334
+ /// If any other read error is encountered then this function immediately
335
+ /// returns. The contents of `buf` are unspecified in this case.
336
+ ///
337
+ /// If this function returns an error, it is unspecified how many bytes it
338
+ /// has read, but it will never read more than would be necessary to
339
+ /// completely fill the buffer.
340
+ fn read_exact ( & mut self , mut buf : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
340
341
while !buf. is_empty ( ) {
341
342
match self . read ( buf) {
342
343
Ok ( 0 ) => break ,
343
344
Ok ( n) => buf = & mut buf[ n..] ,
344
- Err ( e) => return Err ( ReadExactError :: Other ( e ) ) ,
345
+ Err ( e) => return Err ( e ) ,
345
346
}
346
347
}
347
348
if buf. is_empty ( ) {
348
349
Ok ( ( ) )
349
350
} else {
350
- Err ( ReadExactError :: UnexpectedEof )
351
+ Err ( ErrorKind :: UnexpectedEof . into ( ) )
351
352
}
352
353
}
353
354
}
0 commit comments