use thiserror::Error;
#[derive(Debug, Error)]
pub enum TrayError {
#[error("托盘初始化失败: {0}")]
InitFailed(String),
#[error("图标加载失败: {0}")]
IconLoadFailed(String),
#[error("菜单操作失败: {0}")]
MenuFailed(String),
#[error("功能不支持: {0}")]
Unsupported(String),
#[error("托盘已销毁")]
Destroyed,
#[error("系统错误: {0}")]
SystemError(String),
#[error("事件通道已关闭")]
ChannelClosed,
}
pub type TrayResult<T> = Result<T, TrayError>;
impl TrayError {
pub fn is_recoverable(&self) -> bool {
matches!(
self,
TrayError::IconLoadFailed(_) | TrayError::MenuFailed(_)
)
}
pub fn is_unsupported(&self) -> bool {
matches!(self, TrayError::Unsupported(_))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = TrayError::InitFailed("no display".into());
assert!(err.to_string().contains("托盘初始化失败"));
assert!(err.to_string().contains("no display"));
}
#[test]
fn test_recoverable() {
assert!(TrayError::IconLoadFailed("test".into()).is_recoverable());
assert!(TrayError::MenuFailed("test".into()).is_recoverable());
assert!(!TrayError::Destroyed.is_recoverable());
assert!(!TrayError::InitFailed("test".into()).is_recoverable());
}
#[test]
fn test_unsupported() {
assert!(TrayError::Unsupported("double click".into()).is_unsupported());
assert!(!TrayError::Destroyed.is_unsupported());
}
}