unistore-tray 0.1.0

System tray capability for UniStore - cross-platform tray icon, menu, and notifications
Documentation
//! 【错误类型】- TrayError 定义
//!
//! 职责:
//! - 定义托盘操作的所有错误类型
//! - 提供错误分类和上下文信息

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());
    }
}