From d3e2076ea5b04411ea34094005756768787a4951 Mon Sep 17 00:00:00 2001 From: Bruce Leidl Date: Wed, 11 Sep 2019 11:10:27 -0400 Subject: [PATCH] An error class which wraps errno results --- rust/src/system/errno.rs | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 rust/src/system/errno.rs diff --git a/rust/src/system/errno.rs b/rust/src/system/errno.rs new file mode 100644 index 0000000..5db0750 --- /dev/null +++ b/rust/src/system/errno.rs @@ -0,0 +1,70 @@ +use std::fmt::{self, Display}; +use std::io; +use std::result; + +use libc::__errno_location; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Error(i32); +pub type Result = result::Result; + +impl Error { + pub fn from_raw_os_error(e: i32) -> Error { + Error(e) + } + + pub fn last_os_error() -> Error { + Error(unsafe { *__errno_location() }) + } + + pub fn errno(self) -> i32 { + self.0 + } +} + +impl From for Error { + fn from(e: io::Error) -> Self { + Error::from_raw_os_error(e.raw_os_error().unwrap_or_default()) + } +} + +impl std::error::Error for Error {} + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + io::Error::from_raw_os_error(self.0).fmt(f) + } +} + +pub fn errno_result() -> Result { + Err(Error::last_os_error()) +} + +pub fn cvt(t: T) -> io::Result { + if t.is_minus_one() { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} + +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +impl IsMinusOne for i32 { + fn is_minus_one(&self) -> bool { + *self == -1 + } +} +impl IsMinusOne for i64 { + fn is_minus_one(&self) -> bool { + *self == -1 + } +} + +impl IsMinusOne for isize { + fn is_minus_one(&self) -> bool { + *self == -1 + } +}