blitz_ws/
util.rs

1//! Helper traits to ease non-blocking handling.
2
3use std::{
4    io::{Error as IoError, ErrorKind as IoErrorKind},
5    result::Result as StdResult,
6};
7
8use crate::error::Error;
9
10/// Non-blocking IO handling.
11pub trait NonBlockingError: Sized {
12    /// Convert WouldBlock to None and don't touch other errors.
13    fn into_non_blocking(self) -> Option<Self>;
14}
15
16impl NonBlockingError for IoError {
17    fn into_non_blocking(self) -> Option<Self> {
18        match self.kind() {
19            IoErrorKind::WouldBlock => None,
20            _ => Some(self),
21        }
22    }
23}
24
25impl NonBlockingError for Error {
26    fn into_non_blocking(self) -> Option<Self> {
27        match self {
28            Error::Io(io_err) => io_err.into_non_blocking().map(Error::Io),
29            other => Some(other),
30        }
31    }
32}
33
34/// Non-blocking IO wrapper.
35///
36/// This trait is implemented for `Result<T, E: NonBlockingError>`.
37pub trait NonBlockingResult {
38    /// Type of the converted result: `Result<Option<T>, E>`
39    type Result;
40
41    /// Perform the non-block conversion.
42    fn no_block(self) -> Self::Result;
43}
44
45impl<T, E> NonBlockingResult for StdResult<T, E>
46where
47    E: NonBlockingError,
48{
49    type Result = StdResult<Option<T>, E>;
50
51    fn no_block(self) -> Self::Result {
52        match self {
53            Ok(val) => Ok(Some(val)),
54            Err(err) => match err.into_non_blocking() {
55                Some(real_err) => Err(real_err),
56                None => Ok(None),
57            },
58        }
59    }
60}