1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum CoreError {
5 #[error("collection failed: {0}")]
6 Collection(String),
7
8 #[error("process {pid} not found")]
9 ProcessNotFound { pid: u32 },
10
11 #[error("permission denied: {0}")]
12 Permission(String),
13
14 #[error("I/O error: {0}")]
15 Io(#[from] std::io::Error),
16
17 #[error("channel closed")]
18 ChannelClosed,
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24
25 #[test]
26 fn test_error_display() {
27 let variants: Vec<CoreError> = vec![
28 CoreError::Collection("test".into()),
29 CoreError::ProcessNotFound { pid: 42 },
30 CoreError::Permission("denied".into()),
31 CoreError::Io(std::io::Error::other("io err")),
32 CoreError::ChannelClosed,
33 ];
34 for err in &variants {
35 let msg = format!("{err}");
36 assert!(!msg.is_empty(), "Display for {err:?} was empty");
37 }
38 }
39
40 #[test]
41 fn test_error_from_io() {
42 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "not found");
43 let core_err: CoreError = io_err.into();
44 assert!(matches!(core_err, CoreError::Io(_)));
45 }
46
47 #[test]
48 fn test_error_is_send_sync() {
49 fn assert_send_sync<T: Send + Sync>() {}
50 assert_send_sync::<CoreError>();
51 }
52
53 #[test]
54 fn test_error_is_std_error() {
55 let err = CoreError::ChannelClosed;
56 let _boxed: Box<dyn std::error::Error> = Box::new(err);
57 }
58}