1use thiserror::Error;
7
8#[non_exhaustive]
10#[derive(Debug, Error)]
11pub enum PluginError {
12 #[error("plugin load failed: {0}")]
14 LoadFailed(String),
15
16 #[error("plugin execution failed: {0}")]
18 ExecutionFailed(String),
19
20 #[error("permission denied: {0}")]
22 PermissionDenied(String),
23
24 #[error("resource exhausted: {0}")]
26 ResourceExhausted(String),
27
28 #[error("not implemented: {0}")]
30 NotImplemented(String),
31
32 #[error("I/O error: {0}")]
34 Io(#[from] std::io::Error),
35
36 #[error("serialization error: {0}")]
38 Serialization(#[from] serde_json::Error),
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn error_display_load_failed() {
47 let err = PluginError::LoadFailed("bad manifest".into());
48 assert_eq!(err.to_string(), "plugin load failed: bad manifest");
49 }
50
51 #[test]
52 fn error_display_execution_failed() {
53 let err = PluginError::ExecutionFailed("runtime crash".into());
54 assert_eq!(err.to_string(), "plugin execution failed: runtime crash");
55 }
56
57 #[test]
58 fn error_display_permission_denied() {
59 let err = PluginError::PermissionDenied("network access".into());
60 assert_eq!(err.to_string(), "permission denied: network access");
61 }
62
63 #[test]
64 fn error_display_resource_exhausted() {
65 let err = PluginError::ResourceExhausted("fuel limit".into());
66 assert_eq!(err.to_string(), "resource exhausted: fuel limit");
67 }
68
69 #[test]
70 fn error_display_not_implemented() {
71 let err = PluginError::NotImplemented("voice processing".into());
72 assert_eq!(err.to_string(), "not implemented: voice processing");
73 }
74
75 #[test]
76 fn error_from_io() {
77 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file missing");
78 let err = PluginError::from(io_err);
79 assert!(matches!(err, PluginError::Io(_)));
80 assert!(err.to_string().contains("file missing"));
81 }
82
83 #[test]
84 fn error_from_serde_json() {
85 let json_err = serde_json::from_str::<serde_json::Value>("not json").unwrap_err();
86 let err = PluginError::from(json_err);
87 assert!(matches!(err, PluginError::Serialization(_)));
88 }
89
90 #[test]
91 fn all_seven_variants_exist() {
92 let _variants: Vec<PluginError> = vec![
94 PluginError::LoadFailed(String::new()),
95 PluginError::ExecutionFailed(String::new()),
96 PluginError::PermissionDenied(String::new()),
97 PluginError::ResourceExhausted(String::new()),
98 PluginError::NotImplemented(String::new()),
99 PluginError::Io(std::io::Error::new(std::io::ErrorKind::Other, "")),
100 PluginError::Serialization(
101 serde_json::from_str::<serde_json::Value>("!").unwrap_err(),
102 ),
103 ];
104 assert_eq!(_variants.len(), 7);
105 }
106}