unistore-tray 0.1.0

System tray capability for UniStore - cross-platform tray icon, menu, and notifications
Documentation
//! # unistore-tray
//!
//! 跨平台系统托盘能力 - UniStore 能力生态的一部分。
//!
//! ## 功能特性
//!
//! - **跨平台**: 支持 Windows/macOS/Linux
//! - **统一 API**: 屏蔽平台差异,提供一致的接口
//! - **异步友好**: 与 tokio 运行时无缝集成
//! - **事件驱动**: 通过 broadcast channel 订阅托盘事件
//! - **可扩展菜单**: 灵活的菜单构建器 API
//!
//! ## 快速开始
//!
//! ```rust,no_run
//! use unistore_tray::{SystemTray, TrayConfig, TrayEvent, MenuBuilder};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     // 创建托盘配置
//!     let config = TrayConfig::builder()
//!         .tooltip("My App v1.0")
//!         .build();
//!
//!     // 创建系统托盘(需要在主线程)
//!     let tray = SystemTray::new(config)?;
//!
//!     // 设置菜单
//!     let menu = MenuBuilder::new()
//!         .item("open", "打开主窗口")
//!         .separator()
//!         .item("exit", "退出")
//!         .build();
//!     tray.set_menu(menu)?;
//!
//!     // 订阅事件
//!     let mut rx = tray.subscribe();
//!     
//!     // 事件处理循环
//!     while let Ok(event) = rx.recv().await {
//!         match event {
//!             TrayEvent::MenuItemClicked(id) if id.as_str() == "exit" => break,
//!             _ => {}
//!         }
//!     }
//!
//!     Ok(())
//! }
//! ```

mod deps;
mod error;
mod config;
mod event;
mod icon;
mod menu;
mod tray;
mod backend;

// 公开导出
pub use error::{TrayError, TrayResult};
pub use config::{TrayConfig, TrayConfigBuilder};
pub use event::{TrayEvent, MenuItemId};
pub use icon::TrayIcon;
pub use menu::{Menu, MenuItem, MenuBuilder};
pub use tray::SystemTray;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_builder() {
        let config = TrayConfig::builder()
            .tooltip("Test App")
            .event_channel_capacity(128)
            .build();
        
        assert_eq!(config.tooltip, "Test App");
        assert_eq!(config.event_channel_capacity, 128);
    }

    #[test]
    fn test_menu_builder() {
        let menu = MenuBuilder::new()
            .item("open", "打开")
            .separator()
            .check_item("auto_start", "开机启动", true)
            .item("exit", "退出")
            .build();
        
        assert_eq!(menu.items().len(), 4);
    }

    #[test]
    fn test_menu_item_id() {
        let id1: MenuItemId = "test".into();
        let id2 = MenuItemId::new("test");
        assert_eq!(id1, id2);
        assert_eq!(id1.as_str(), "test");
    }

    #[test]
    fn test_tray_event_debug() {
        let event = TrayEvent::Click;
        assert!(format!("{:?}", event).contains("Click"));
        
        let event = TrayEvent::MenuItemClicked(MenuItemId::new("exit"));
        assert!(format!("{:?}", event).contains("exit"));
    }
}