1use std::ffi::CStr;
2use std::fmt;
3use std::io;
4use std::str;
5
6use std::error::Error as StdError;
7use std::result::Result as StdResult;
8
9use libc::c_int;
10
11pub type Result<T> = StdResult<T,Error>;
13
14#[derive(Debug,Clone,Copy,PartialEq,Eq)]
16pub enum ErrorKind {
17 NoMem,
18 InvalidInput,
19 Io(io::ErrorKind),
20}
21
22#[derive(Debug)]
24pub struct Error {
25 errno: c_int,
26}
27
28impl Error {
29 fn strerror(&self) -> &str {
30 unsafe {
31 str::from_utf8_unchecked(CStr::from_ptr(::libc::strerror(self.errno)).to_bytes())
32 }
33 }
34
35 pub fn kind(&self) -> ErrorKind {
37 match self.errno {
38 ::libc::ENOMEM => ErrorKind::NoMem,
39 ::libc::EINVAL => ErrorKind::InvalidInput,
40 errno => ErrorKind::Io(io::Error::from_raw_os_error(errno).kind()),
41 }
42 }
43
44 pub fn description(&self) -> &str {
46 self.strerror()
47 }
48}
49
50impl fmt::Display for Error {
51 fn fmt(&self, fmt: &mut fmt::Formatter) -> StdResult<(),fmt::Error> {
52 fmt.write_str(self.strerror())
53 }
54}
55
56impl StdError for Error {
57 fn description(&self) -> &str {
58 self.strerror()
59 }
60}
61
62impl From<Error> for io::Error {
63 fn from(error: Error) -> io::Error {
64 let io_error_kind = match error.kind() {
65 ErrorKind::Io(kind) => kind,
66 ErrorKind::InvalidInput => io::ErrorKind::InvalidInput,
67 ErrorKind::NoMem => io::ErrorKind::Other,
68 };
69
70 io::Error::new(io_error_kind, error.strerror())
71 }
72}
73
74pub fn from_errno(errno: c_int) -> Error {
75 Error { errno: -errno }
76}