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