@@ -99,6 +99,10 @@ pub enum ErrorKind {
9999 ///
100100 /// [`InvalidInput`]: ErrorKind::InvalidInput
101101 InvalidData ,
102+ /// The underlying storage (typically, a filesystem) is full.
103+ ///
104+ /// This does not include out of quota errors.
105+ StorageFull ,
102106 /// The I/O operation's timeout expired, causing it to be canceled.
103107 TimedOut ,
104108 /// This operation was interrupted.
@@ -109,6 +113,13 @@ pub enum ErrorKind {
109113 ///
110114 /// This means that the operation can never succeed.
111115 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 ,
112123 /// An operation could not be completed, because it failed
113124 /// to allocate enough memory.
114125 OutOfMemory ,
@@ -133,9 +144,11 @@ impl From<ErrorKind> for std::io::ErrorKind {
133144 ErrorKind :: AlreadyExists => std:: io:: ErrorKind :: AlreadyExists ,
134145 ErrorKind :: InvalidInput => std:: io:: ErrorKind :: InvalidInput ,
135146 ErrorKind :: InvalidData => std:: io:: ErrorKind :: InvalidData ,
147+ ErrorKind :: StorageFull => std:: io:: ErrorKind :: StorageFull ,
136148 ErrorKind :: TimedOut => std:: io:: ErrorKind :: TimedOut ,
137149 ErrorKind :: Interrupted => std:: io:: ErrorKind :: Interrupted ,
138150 ErrorKind :: Unsupported => std:: io:: ErrorKind :: Unsupported ,
151+ ErrorKind :: UnexpectedEof => std:: io:: ErrorKind :: UnexpectedEof ,
139152 ErrorKind :: OutOfMemory => std:: io:: ErrorKind :: OutOfMemory ,
140153 _ => std:: io:: ErrorKind :: Other ,
141154 }
@@ -159,9 +172,11 @@ impl From<std::io::ErrorKind> for ErrorKind {
159172 std:: io:: ErrorKind :: AlreadyExists => ErrorKind :: AlreadyExists ,
160173 std:: io:: ErrorKind :: InvalidInput => ErrorKind :: InvalidInput ,
161174 std:: io:: ErrorKind :: InvalidData => ErrorKind :: InvalidData ,
175+ std:: io:: ErrorKind :: StorageFull => ErrorKind :: StorageFull ,
162176 std:: io:: ErrorKind :: TimedOut => ErrorKind :: TimedOut ,
163177 std:: io:: ErrorKind :: Interrupted => ErrorKind :: Interrupted ,
164178 std:: io:: ErrorKind :: Unsupported => ErrorKind :: Unsupported ,
179+ std:: io:: ErrorKind :: UnexpectedEof => ErrorKind :: UnexpectedEof ,
165180 std:: io:: ErrorKind :: OutOfMemory => ErrorKind :: OutOfMemory ,
166181 _ => ErrorKind :: Other ,
167182 }
@@ -172,17 +187,11 @@ impl From<std::io::ErrorKind> for ErrorKind {
172187///
173188/// This trait allows generic code to do limited inspecting of errors,
174189/// to react differently to different kinds.
175- pub trait Error : core:: error:: Error {
190+ pub trait Error : core:: error:: Error + From < ErrorKind > {
176191 /// Get the kind of this error.
177192 fn kind ( & self ) -> ErrorKind ;
178193}
179194
180- impl Error for core:: convert:: Infallible {
181- fn kind ( & self ) -> ErrorKind {
182- match * self { }
183- }
184- }
185-
186195impl Error for ErrorKind {
187196 fn kind ( & self ) -> ErrorKind {
188197 * self
@@ -205,6 +214,14 @@ impl Error for std::io::Error {
205214 }
206215}
207216
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+
208225/// Base trait for all IO traits, defining the error type.
209226///
210227/// 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 {
223240 type Error = T :: Error ;
224241}
225242
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-
264243/// Errors that could be returned by `Write` on `&mut [u8]`.
265244#[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
266245#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
@@ -326,6 +305,15 @@ pub trait Read: ErrorType {
326305 ///
327306 /// If `buf.len() == 0`, `read` returns without blocking, with either `Ok(0)` or an error.
328307 /// 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.
329317 fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > ;
330318
331319 /// Read the exact number of bytes required to fill `buf`.
@@ -336,18 +324,31 @@ pub trait Read: ErrorType {
336324 /// If you are using [`ReadReady`] to avoid blocking, you should not use this function.
337325 /// `ReadReady::read_ready()` returning true only guarantees the first call to `read()` will
338326 /// 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 > {
340341 while !buf. is_empty ( ) {
341342 match self . read ( buf) {
342343 Ok ( 0 ) => break ,
343344 Ok ( n) => buf = & mut buf[ n..] ,
344- Err ( e) => return Err ( ReadExactError :: Other ( e ) ) ,
345+ Err ( e) => return Err ( e ) ,
345346 }
346347 }
347348 if buf. is_empty ( ) {
348349 Ok ( ( ) )
349350 } else {
350- Err ( ReadExactError :: UnexpectedEof )
351+ Err ( ErrorKind :: UnexpectedEof . into ( ) )
351352 }
352353 }
353354}
0 commit comments