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