sstable/
error.rs

1use std::convert::From;
2use std::error::Error;
3use std::fmt::{self, Display, Formatter};
4use std::io;
5use std::result;
6use std::sync;
7
8use snap;
9
10/// StatusCode describes various failure modes of database operations.
11#[derive(Clone, Debug, PartialEq)]
12#[allow(dead_code)]
13pub enum StatusCode {
14    OK,
15
16    AlreadyExists,
17    Corruption,
18    CompressionError,
19    IOError,
20    InvalidArgument,
21    InvalidData,
22    LockError,
23    NotFound,
24    NotSupported,
25    PermissionDenied,
26    Unknown,
27}
28
29/// Status encapsulates a `StatusCode` and an error message. It can be displayed, and also
30/// implements `Error`. io::Error can be converted into Status.
31#[derive(Clone, Debug, PartialEq)]
32pub struct Status {
33    pub code: StatusCode,
34    pub err: String,
35}
36
37impl Default for Status {
38    fn default() -> Status {
39        Status {
40            code: StatusCode::OK,
41            err: String::new(),
42        }
43    }
44}
45
46impl Display for Status {
47    fn fmt(&self, fmt: &mut Formatter) -> result::Result<(), fmt::Error> {
48        fmt.write_str(&self.to_string())
49    }
50}
51
52impl Error for Status {
53    fn description(&self) -> &str {
54        &self.err
55    }
56}
57
58impl Status {
59    pub fn new(code: StatusCode, msg: &str) -> Status {
60        let err;
61        if msg.is_empty() {
62            err = format!("{:?}", code)
63        } else {
64            err = format!("{:?}: {}", code, msg);
65        }
66        return Status {
67            code: code,
68            err: err,
69        };
70    }
71}
72
73impl From<io::Error> for Status {
74    fn from(e: io::Error) -> Status {
75        let c = match e.kind() {
76            io::ErrorKind::NotFound => StatusCode::NotFound,
77            io::ErrorKind::InvalidData => StatusCode::Corruption,
78            io::ErrorKind::InvalidInput => StatusCode::InvalidArgument,
79            io::ErrorKind::PermissionDenied => StatusCode::PermissionDenied,
80            _ => StatusCode::IOError,
81        };
82
83        Status::new(c, &e.to_string())
84    }
85}
86
87impl<T> From<sync::PoisonError<T>> for Status {
88    fn from(_: sync::PoisonError<T>) -> Status {
89        Status::new(StatusCode::LockError, "lock poisoned")
90    }
91}
92
93impl From<snap::Error> for Status {
94    fn from(e: snap::Error) -> Status {
95        Status {
96            code: StatusCode::CompressionError,
97            err: e.to_string(),
98        }
99    }
100}
101
102/// The sstable result type.
103pub type Result<T> = result::Result<T, Status>;
104
105/// err returns a new Status wrapped in a Result.
106pub fn err<T>(code: StatusCode, msg: &str) -> Result<T> {
107    Err(Status::new(code, msg))
108}