fmmap/
error.rs

1use parse_display::Display;
2use std::io;
3
4/// alias for [`Result<T, Error>`]
5///
6/// [`Result<T, Error>`]: struct.Error.html
7pub type Result<T> = std::result::Result<T, Error>;
8
9/// ErrorKind in this crate.
10#[derive(Copy, Clone, Eq, PartialEq, Display, Debug)]
11pub enum ErrorKind {
12    /// unexpected EOF
13    #[display("unexpected EOF")]
14    EOF,
15
16    /// IO error
17    #[display("IO error")]
18    IO,
19
20    /// Truncation failed
21    #[display("truncation failed")]
22    TruncationFailed,
23
24    /// unable to open file
25    #[display("unable to open file")]
26    OpenFailed,
27
28    /// unable to open dir
29    #[display("unable to open dir")]
30    OpenDirFailed,
31
32    /// flush file failed
33    #[display("flush file failed")]
34    FlushFailed,
35
36    /// sync dir failed
37    #[display("sync file failed")]
38    SyncFileFailed,
39
40    /// sync dir failed
41    #[display("sync dir failed")]
42    SyncDirFailed,
43
44    /// mmap failed
45    #[display("mmap failed")]
46    MmapFailed,
47
48    /// remmap failed
49    #[display("remmap failed")]
50    RemmapFailed,
51
52    /// invalid range
53    #[display("range start must not be greater than end: {0} <= {1}")]
54    InvalidBound(usize, usize),
55
56    /// out of range
57    #[display("range end out of bounds: {0} <= {1}")]
58    OutOfBound(usize, usize),
59
60    /// call on an empty mmap file
61    #[display("call on an empty mmap file")]
62    InvokeEmptyMmap,
63
64    /// not a directory
65    #[cfg(not(feature = "nightly"))]
66    #[display("not a directory")]
67    NotADirectory,
68}
69
70enum Repr {
71    Simple(ErrorKind),
72    Message { kd: ErrorKind, msg: String },
73    Source(Box<Source>),
74    SourceMessage { msg: String, src: Box<Source> },
75}
76
77struct Source {
78    kind: ErrorKind,
79    error: Box<dyn std::error::Error + Send + Sync>,
80}
81
82/// Error in this crate
83pub struct Error {
84    repr: Repr,
85}
86
87impl Error {
88    pub(crate) fn new<E>(kd: ErrorKind, src: E) -> Self
89    where
90        E: Into<Box<dyn std::error::Error + Send + Sync>>,
91    {
92        Self::_new(kd, src.into())
93    }
94
95    fn _new(kind: ErrorKind, error: Box<dyn std::error::Error + Send + Sync>) -> Self {
96        Error {
97            repr: Repr::Source(Box::new(Source { kind, error })),
98        }
99    }
100
101    pub(crate) fn new_with_message<M>(kd: ErrorKind, msg: M) -> Self
102    where
103        M: Into<String>,
104    {
105        Self {
106            repr: Repr::Message {
107                kd,
108                msg: msg.into(),
109            },
110        }
111    }
112
113    pub(crate) fn new_source_msg<M, E>(kd: ErrorKind, msg: M, src: E) -> Self
114    where
115        E: Into<Box<dyn std::error::Error + Send + Sync>>,
116        M: Into<String>,
117    {
118        Self {
119            repr: Repr::SourceMessage {
120                msg: msg.into(),
121                src: Box::new(Source {
122                    kind: kd,
123                    error: src.into(),
124                }),
125            },
126        }
127    }
128
129    pub(crate) fn f(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130        match &self.repr {
131            Repr::Simple(kd) => write!(formatter, "{}", kd),
132            Repr::Source(src) => write!(formatter, "{}: {}", src.error, src.kind),
133            Repr::Message { kd, msg } => write!(formatter, "{}: {}", msg, kd),
134            Repr::SourceMessage { msg, src } => {
135                write!(formatter, "{}: {}: {}", msg, src.kind, src.error)
136            }
137        }
138    }
139
140    /// Return the [`ErrorKind`] of this error
141    ///
142    /// [`ErrorKind`]: struct.ErrorKind.html
143    pub fn kind(&self) -> ErrorKind {
144        match &self.repr {
145            Repr::Simple(kd) => *kd,
146            Repr::Message { kd, msg: _ } => *kd,
147            Repr::Source(src) => src.kind,
148            Repr::SourceMessage { msg: _, src } => src.kind,
149        }
150    }
151}
152
153impl From<ErrorKind> for Error {
154    fn from(kd: ErrorKind) -> Self {
155        Self {
156            repr: Repr::Simple(kd),
157        }
158    }
159}
160
161impl std::fmt::Debug for Error {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        self.f(f)
164    }
165}
166
167impl std::fmt::Display for Error {
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169        self.f(f)
170    }
171}
172
173impl std::error::Error for Error {
174    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
175        match self.repr {
176            Repr::Simple(_) => None,
177            Repr::Source(ref c) => Some(c.error.as_ref()),
178            Repr::Message { .. } => None,
179            Repr::SourceMessage { msg: _, ref src } => Some(src.error.as_ref()),
180        }
181    }
182}
183
184impl From<io::Error> for Error {
185    fn from(err: io::Error) -> Self {
186        match err.kind() {
187            io::ErrorKind::UnexpectedEof => Error::new(ErrorKind::EOF, err),
188            _ => Error::new(ErrorKind::IO, err),
189        }
190    }
191}