xentrace_parser/error.rs
1use std::{error, fmt, io, result};
2
3pub type Result<T> = result::Result<T, Error>;
4
5#[derive(Debug)]
6pub struct Error {
7 message: String,
8 source: ErrorSource,
9}
10
11#[derive(Debug)]
12pub enum ErrorSource {
13 /// Error originating from I/O operations.
14 Io(io::Error),
15 /// Error source is none.
16 None,
17}
18
19impl Error {
20 /// Constructs a new `Error` with a custom message and no source.
21 pub(crate) fn new<T: fmt::Display>(msg: T) -> Self {
22 Self {
23 message: msg.to_string(),
24 source: ErrorSource::None,
25 }
26 }
27
28 /// Constructs a new `Error` originating from an I/O error with a custom message.
29 pub(crate) fn io_error<T: fmt::Display>(msg: T, source: io::Error) -> Self {
30 Self {
31 message: msg.to_string(),
32 source: ErrorSource::Io(source),
33 }
34 }
35}
36
37impl Error {
38 /// Returns a reference to the source of the error.
39 ///
40 /// # Examples
41 ///
42 /// ```
43 /// use std::io;
44 /// use xentrace_parser::{Error, error::ErrorSource};
45 ///
46 /// let io_error = io::Error::new(io::ErrorKind::NotFound, "File not found");
47 /// let custom_error = Error::io_error("Custom I/O error", io_error);
48 ///
49 /// assert_eq!(custom_error.error_source(), &ErrorSource::Io(io_error));
50 /// ```
51 pub fn error_source(&self) -> &ErrorSource {
52 &self.source
53 }
54
55 /// Returns the OS error that this error represents, if applicable.
56 ///
57 /// # Examples
58 ///
59 /// ```
60 /// use std::io;
61 /// use xentrace_parser::{Error, error::ErrorSource};
62 ///
63 /// let io_error = io::Error::from_raw_os_error(2);
64 /// let custom_error = Error::io_error("Custom I/O error", io_error);
65 ///
66 /// assert_eq!(custom_error.raw_os_error(), Some(2));
67 /// ```
68 pub fn raw_os_error(&self) -> Option<i32> {
69 match &self.source {
70 ErrorSource::Io(source) => source.raw_os_error(),
71 _ => None,
72 }
73 }
74}
75
76impl fmt::Display for Error {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 f.write_str(&self.message)?;
79
80 match &self.source {
81 ErrorSource::Io(source) => {
82 f.write_fmt(format_args!(": {}", source))?;
83 }
84 ErrorSource::None => (),
85 }
86
87 Ok(())
88 }
89}
90
91impl error::Error for Error {
92 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
93 match &self.source {
94 ErrorSource::Io(source) => Some(source),
95 ErrorSource::None => None,
96 }
97 }
98}