From fae1357e79ff18e7955fa6ba9c7cea9e13034adf Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 2 Apr 2019 23:30:34 +0000 Subject: [PATCH] jemalloc-ctl: impl std::error::Error for Error --- jemalloc-ctl/src/error.rs | 75 ++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/jemalloc-ctl/src/error.rs b/jemalloc-ctl/src/error.rs index 6812ee8..b8db58b 100644 --- a/jemalloc-ctl/src/error.rs +++ b/jemalloc-ctl/src/error.rs @@ -32,34 +32,61 @@ pub type Result = result::Result; impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0.get() as c_int { - libc::EINVAL => write!( - f, - "`newp` is not `NULL`, and `newlen` is too large or too \ - small. Alternatively, `*oldlenp` is too large or too \ - small; in this case as much data as possible are read \ - despite the error." - ), - libc::ENOENT => write!( - f, - "`name` or `mib` specifies an unknown/invalid value." - ), - libc::EPERM => write!( - f, - "Attempt to read or write `void` value, or attempt to \ - write read-only value." - ), - libc::EAGAIN => write!(f, "A memory allocation failure occurred."), - libc::EFAULT => write!( - f, - "An interface with side effects failed in some way not \ - directly related to `mallctl*()` read/write processing." - ), - v => write!(f, "Unknown error code: \"{}\".", v), + let code = self.0.get() as c_int; + match description(code) { + Some(m) => write!(f, "{}", m), + None => write!(f, "Unknown error code: \"{}\".", code), } } } +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(self, f) + } +} + +#[cfg(feature = "use_std")] +use std::error::Error as StdError; + +#[cfg(feature = "use_std")] +impl StdError for Error { + fn description(&self) -> &str { + match description(self.0.get() as c_int) { + Some(m) => m, + None => "Unknown error" + } + } + fn cause(&self) -> Option<&dyn StdError> { None } + fn source(&self) -> Option<&(dyn StdError + 'static)> { None } +} + +fn description(code: c_int) -> Option<&'static str> { + match code { + libc::EINVAL => Some( + "`newp` is not `NULL`, and `newlen` is too large or too \ + small. Alternatively, `*oldlenp` is too large or too \ + small; in this case as much data as possible are read \ + despite the error." + ), + libc::ENOENT => Some( + "`name` or `mib` specifies an unknown/invalid value." + ), + libc::EPERM => Some( + "Attempt to read or write `void` value, or attempt to \ + write read-only value." + ), + libc::EAGAIN => Some( + "A memory allocation failure occurred." + ), + libc::EFAULT => Some( + "An interface with side effects failed in some way not \ + directly related to `mallctl*()` read/write processing." + ), + _ => None + } +} + pub(crate) fn cvt(ret: c_int) -> Result<()> { match ret { 0 => Ok(()),