use std::{ io::{Error, ErrorKind, Result}, process::ExitStatus, result, }; use ipc_channel::ipc; use nix::sys::wait; pub trait ToIOResult { fn to_io_result(self) -> Result; } impl ToIOResult for nix::Result { fn to_io_result(self) -> Result { self.map_err(|error| match error { nix::Error::Sys(code) => Error::from_raw_os_error(code as i32), _ => Error::new(ErrorKind::Other, error), }) } } pub trait Checkable { fn check(&self) -> Result<()>; } impl Checkable for ExitStatus { fn check(&self) -> Result<()> { if self.success() { Ok(()) } else { Err(Error::new( ErrorKind::Other, format!("process exited with status {}", self), )) } } } impl Checkable for wait::WaitStatus { fn check(&self) -> Result<()> { match self { wait::WaitStatus::Exited(_, 0) => Ok(()), _ => Err(Error::new( ErrorKind::Other, format!("process exited with status {:?}", self), )), } } } pub trait CheckDisconnect { type Output; fn check_disconnect(self) -> Result; } impl CheckDisconnect for result::Result { type Output = result::Result<(), T>; fn check_disconnect(self) -> Result { match self { Ok(v) => Ok(Err(v)), Err(ipc::IpcError::Disconnected) => Ok(Ok(())), Err(error) => Err(Error::new(ErrorKind::Other, format!("{:?}", error))), } } }