duende_platform/
error.rs

1//! Platform error types.
2
3/// Result type alias for platform operations.
4pub type Result<T> = std::result::Result<T, PlatformError>;
5
6/// Platform-specific errors.
7#[derive(Debug, thiserror::Error)]
8pub enum PlatformError {
9    /// Platform not supported.
10    #[error("platform not supported: {0}")]
11    NotSupported(String),
12
13    /// Feature not implemented.
14    #[error("not implemented: {0}")]
15    NotImplemented(&'static str),
16
17    /// Spawn failed.
18    #[error("failed to spawn daemon: {0}")]
19    Spawn(String),
20
21    /// Signal failed.
22    #[error("failed to send signal: {0}")]
23    Signal(String),
24
25    /// Status query failed.
26    #[error("failed to get status: {0}")]
27    Status(String),
28
29    /// Tracer attachment failed.
30    #[error("failed to attach tracer: {0}")]
31    Tracer(String),
32
33    /// Resource allocation or configuration failed.
34    #[error("resource error: {0}")]
35    Resource(String),
36
37    /// I/O error.
38    #[error("I/O error: {0}")]
39    Io(#[from] std::io::Error),
40
41    /// Core daemon error.
42    #[error("daemon error: {0}")]
43    Daemon(#[from] duende_core::DaemonError),
44}
45
46impl PlatformError {
47    /// Creates a not supported error.
48    #[must_use]
49    pub fn not_supported(msg: impl Into<String>) -> Self {
50        Self::NotSupported(msg.into())
51    }
52
53    /// Creates a spawn error.
54    #[must_use]
55    pub fn spawn(msg: impl Into<String>) -> Self {
56        Self::Spawn(msg.into())
57    }
58
59    /// Creates a signal error.
60    #[must_use]
61    pub fn signal(msg: impl Into<String>) -> Self {
62        Self::Signal(msg.into())
63    }
64
65    /// Creates a resource error.
66    #[must_use]
67    pub fn resource(msg: impl Into<String>) -> Self {
68        Self::Resource(msg.into())
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_not_supported_error() {
78        let err = PlatformError::not_supported("macOS cgroups");
79        assert!(err.to_string().contains("not supported"));
80        assert!(err.to_string().contains("macOS cgroups"));
81    }
82
83    #[test]
84    fn test_spawn_error() {
85        let err = PlatformError::spawn("binary not found");
86        assert!(err.to_string().contains("spawn"));
87        assert!(err.to_string().contains("binary not found"));
88    }
89
90    #[test]
91    fn test_signal_error() {
92        let err = PlatformError::signal("process not found");
93        assert!(err.to_string().contains("signal"));
94    }
95
96    #[test]
97    fn test_resource_error() {
98        let err = PlatformError::resource("memory exhausted");
99        assert!(err.to_string().contains("resource"));
100    }
101
102    #[test]
103    fn test_not_implemented_error() {
104        let err = PlatformError::NotImplemented("systemd integration");
105        assert!(err.to_string().contains("not implemented"));
106    }
107
108    #[test]
109    fn test_status_error() {
110        let err = PlatformError::Status("connection refused".into());
111        assert!(err.to_string().contains("status"));
112    }
113
114    #[test]
115    fn test_tracer_error() {
116        let err = PlatformError::Tracer("ptrace denied".into());
117        assert!(err.to_string().contains("tracer"));
118    }
119
120    #[test]
121    fn test_io_error_conversion() {
122        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
123        let err: PlatformError = io_err.into();
124        assert!(err.to_string().contains("I/O error"));
125    }
126}