1use std::error::Error;
4use std::fmt;
5
6#[derive(Debug)]
11pub enum AspectError {
12 ExecutionError {
14 message: String,
16 source: Option<Box<dyn Error + Send + Sync>>,
18 },
19
20 WeavingError {
22 message: String,
24 },
25
26 Custom(Box<dyn Error + Send + Sync>),
28}
29
30impl AspectError {
31 pub fn execution(message: impl Into<String>) -> Self {
41 Self::ExecutionError {
42 message: message.into(),
43 source: None,
44 }
45 }
46
47 pub fn execution_with_source(
59 message: impl Into<String>,
60 source: impl Error + Send + Sync + 'static,
61 ) -> Self {
62 Self::ExecutionError {
63 message: message.into(),
64 source: Some(Box::new(source)),
65 }
66 }
67
68 pub fn weaving(message: impl Into<String>) -> Self {
78 Self::WeavingError {
79 message: message.into(),
80 }
81 }
82
83 pub fn custom(error: impl Error + Send + Sync + 'static) -> Self {
95 Self::Custom(Box::new(error))
96 }
97}
98
99impl fmt::Display for AspectError {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 match self {
102 Self::ExecutionError { message, .. } => {
103 write!(f, "Execution error: {}", message)
104 }
105 Self::WeavingError { message } => {
106 write!(f, "Weaving error: {}", message)
107 }
108 Self::Custom(err) => write!(f, "Custom error: {}", err),
109 }
110 }
111}
112
113impl Error for AspectError {
114 fn source(&self) -> Option<&(dyn Error + 'static)> {
115 match self {
116 Self::ExecutionError { source, .. } => {
117 source.as_ref().map(|e| e.as_ref() as &(dyn Error + 'static))
118 }
119 Self::Custom(err) => Some(err.as_ref()),
120 _ => None,
121 }
122 }
123}
124
125impl From<String> for AspectError {
127 fn from(s: String) -> Self {
128 Self::execution(s)
129 }
130}
131
132impl From<&str> for AspectError {
133 fn from(s: &str) -> Self {
134 Self::execution(s)
135 }
136}
137
138impl From<Box<dyn Error + Send + Sync>> for AspectError {
139 fn from(err: Box<dyn Error + Send + Sync>) -> Self {
140 Self::Custom(err)
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use std::io;
148
149 #[test]
150 fn test_execution_error() {
151 let err = AspectError::execution("test error");
152 assert!(matches!(err, AspectError::ExecutionError { .. }));
153 assert_eq!(err.to_string(), "Execution error: test error");
154 }
155
156 #[test]
157 fn test_execution_error_with_source() {
158 let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
159 let err = AspectError::execution_with_source("read failed", io_err);
160
161 assert!(err.source().is_some());
162 }
163
164 #[test]
165 fn test_weaving_error() {
166 let err = AspectError::weaving("invalid pointcut");
167 assert!(matches!(err, AspectError::WeavingError { .. }));
168 assert_eq!(err.to_string(), "Weaving error: invalid pointcut");
169 }
170
171 #[test]
172 fn test_custom_error() {
173 let io_err = io::Error::new(io::ErrorKind::Other, "custom");
174 let err = AspectError::custom(io_err);
175
176 assert!(matches!(err, AspectError::Custom(_)));
177 }
178
179 #[test]
180 fn test_from_string() {
181 let err: AspectError = "error message".into();
182 assert!(matches!(err, AspectError::ExecutionError { .. }));
183 }
184}