Skip to main content

module_util/evaluator/dfs/
error.rs

1//! [`Evaluator`] error.
2//!
3//! [`Evaluator`]: super::Evaluator
4
5use core::fmt;
6
7use alloc::boxed::Box;
8
9///////////////////////////////////////////////////////////////////////////////
10
11/// Error returned by [`Dfs`].
12///
13/// # Example
14///
15/// ```rust
16/// # use module_util::evaluator::dfs::error::Error;
17/// use std::io;
18///
19/// let err = Error::Merge(module::merge::Error::collision());
20/// assert_eq!(format!("{err}"), "value collision");
21/// assert_eq!(format!("{err:#}"), "value collision");
22///
23/// let err = Error::other(io::Error::other("invalid data"));
24/// assert_eq!(format!("{err}"), "invalid data");
25/// assert_eq!(format!("{err:#}"), "other error");
26/// ```
27///
28/// [`Dfs`]: super::Dfs
29#[derive(Debug)]
30pub enum Error {
31    /// An error during the [`Merge`] operation.
32    ///
33    /// [`Merge`]: module::merge::Merge
34    Merge(module::merge::Error),
35
36    /// An error during some other operation during evaluation.
37    Other(Box<dyn core::error::Error + Send + Sync + 'static>),
38}
39
40impl fmt::Display for Error {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        match self {
43            Self::Merge(x) => fmt::Display::fmt(x, f),
44            Self::Other(x) => {
45                if f.alternate() {
46                    f.write_str("other error")
47                } else {
48                    fmt::Display::fmt(x, f)
49                }
50            }
51        }
52    }
53}
54
55impl core::error::Error for Error {
56    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
57        match self {
58            Self::Merge(x) => Some(x),
59            Self::Other(x) => Some(&**x),
60        }
61    }
62}
63
64impl Error {
65    /// Create new error from `error`.
66    #[must_use]
67    pub fn other<E>(error: E) -> Self
68    where
69        E: core::error::Error + Send + Sync + 'static,
70    {
71        Self::Other(Box::new(error))
72    }
73
74    /// Check whether the error is a merge error.
75    ///
76    /// Equivalent to: `matches!(self, Self::Merge(_))`.
77    #[inline]
78    #[must_use]
79    pub fn is_merge(&self) -> bool {
80        matches!(self, Self::Merge(_))
81    }
82
83    /// Get a reference to the inner merge error.
84    #[must_use]
85    pub fn as_merge(&self) -> Option<&module::merge::Error> {
86        match self {
87            Self::Merge(x) => Some(x),
88            _ => None,
89        }
90    }
91
92    /// Get a mutable reference to the inner merge error.
93    #[must_use]
94    pub fn as_merge_mut(&mut self) -> Option<&mut module::merge::Error> {
95        match self {
96            Self::Merge(x) => Some(x),
97            _ => None,
98        }
99    }
100
101    /// Check whether the error is of another kind.
102    ///
103    /// Equivalent to: `matches!(self, Self::Other(_))`.
104    #[inline]
105    #[must_use]
106    pub fn is_other(&self) -> bool {
107        matches!(self, Self::Other(_))
108    }
109
110    /// Get a reference to the inner error.
111    #[must_use]
112    pub fn as_other(&self) -> Option<&(dyn core::error::Error + 'static)> {
113        match self {
114            Self::Other(x) => Some(&**x),
115            _ => None,
116        }
117    }
118
119    /// Get a mutable reference to the inner error.
120    #[must_use]
121    pub fn as_other_mut(&mut self) -> Option<&mut (dyn core::error::Error + 'static)> {
122        match self {
123            Self::Other(x) => Some(&mut **x),
124            _ => None,
125        }
126    }
127}
128
129///////////////////////////////////////////////////////////////////////////////
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn test_is_send_sync() {
137        fn assert_send_sync<T: Send + Sync>() {}
138        assert_send_sync::<Error>();
139    }
140}