mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-28 06:23:08 -08:00
feat: Convenience functions and traits to automatically handle ErrorKind::{Interrupt, WouldBlock}
This commit is contained in:
@@ -49,3 +49,62 @@ impl<T, E: TryIoErrorKind> TryIoResultKindHintExt<T> for Result<T, E> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Automatically handles `std::io::ErrorKind::Interrupted`.
|
||||||
|
///
|
||||||
|
/// - If there is no error (i.e. on `Ok(r)`), the function will return `Ok(Some(r))`
|
||||||
|
/// - `Interrupted` is handled internally, by retrying the IO operation
|
||||||
|
/// - Other errors are returned as is
|
||||||
|
pub fn handle_interrupted<R, E, F>(mut iofn: F) -> Result<Option<R>, E>
|
||||||
|
where
|
||||||
|
E: TryIoErrorKind,
|
||||||
|
F: FnMut() -> Result<R, E>,
|
||||||
|
{
|
||||||
|
use io::ErrorKind as E;
|
||||||
|
loop {
|
||||||
|
match iofn().try_io_err_kind_hint() {
|
||||||
|
Ok(v) => return Ok(Some(v)),
|
||||||
|
Err((_, Some(E::Interrupted))) => continue, // try again
|
||||||
|
Err((e, _)) => return Err(e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Automatically handles `std::io::ErrorKind::{WouldBlock, Interrupted}`.
|
||||||
|
///
|
||||||
|
/// - If there is no error (i.e. on `Ok(r)`), the function will return `Ok(Some(r))`
|
||||||
|
/// - `Interrupted` is handled internally, by retrying the IO operation
|
||||||
|
/// - `WouldBlock` is handled by returning `Ok(None)`,
|
||||||
|
/// - Other errors are returned as is
|
||||||
|
pub fn nonblocking_handle_io_errors<R, E, F>(mut iofn: F) -> Result<Option<R>, E>
|
||||||
|
where
|
||||||
|
E: TryIoErrorKind,
|
||||||
|
F: FnMut() -> Result<R, E>,
|
||||||
|
{
|
||||||
|
use io::ErrorKind as E;
|
||||||
|
loop {
|
||||||
|
match iofn().try_io_err_kind_hint() {
|
||||||
|
Ok(v) => return Ok(Some(v)),
|
||||||
|
Err((_, Some(E::WouldBlock))) => return Ok(None), // no data to read
|
||||||
|
Err((_, Some(E::Interrupted))) => continue, // try again
|
||||||
|
Err((e, _)) => return Err(e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ReadNonblockingWithBoringErrorsHandledExt {
|
||||||
|
/// Convenience wrapper using [nonblocking_handle_io_errors] with [std::io::Read]
|
||||||
|
fn read_nonblocking_with_boring_errors_handled(
|
||||||
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
|
) -> io::Result<Option<usize>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: io::Read> ReadNonblockingWithBoringErrorsHandledExt for T {
|
||||||
|
fn read_nonblocking_with_boring_errors_handled(
|
||||||
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
|
) -> io::Result<Option<usize>> {
|
||||||
|
nonblocking_handle_io_errors(|| self.read(buf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user