mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-27 22:13:12 -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