unistore-tray 0.1.0

System tray capability for UniStore - cross-platform tray icon, menu, and notifications
Documentation
//! 【配置结构】- TrayConfig 定义
//!
//! 职责:
//! - 定义托盘配置选项
//! - 提供构建器模式

use crate::deps::PathBuf;

/// 托盘配置
#[derive(Debug, Clone)]
pub struct TrayConfig {
    /// 应用标识
    pub app_id: String,
    /// 默认提示文字(鼠标悬停显示)
    pub tooltip: String,
    /// 图标路径(None 使用默认图标)
    pub icon_path: Option<PathBuf>,
    /// 事件通道容量
    pub event_channel_capacity: usize,
}

impl Default for TrayConfig {
    fn default() -> Self {
        Self {
            app_id: "unistore".into(),
            tooltip: "UniStore".into(),
            icon_path: None,
            event_channel_capacity: 64,
        }
    }
}

impl TrayConfig {
    /// 创建配置构建器
    pub fn builder() -> TrayConfigBuilder {
        TrayConfigBuilder::default()
    }
}

/// 托盘配置构建器
#[derive(Debug, Default)]
pub struct TrayConfigBuilder {
    app_id: Option<String>,
    tooltip: Option<String>,
    icon_path: Option<PathBuf>,
    event_channel_capacity: Option<usize>,
}

impl TrayConfigBuilder {
    /// 设置应用标识
    pub fn app_id(mut self, app_id: impl Into<String>) -> Self {
        self.app_id = Some(app_id.into());
        self
    }

    /// 设置提示文字
    pub fn tooltip(mut self, tooltip: impl Into<String>) -> Self {
        self.tooltip = Some(tooltip.into());
        self
    }

    /// 设置图标路径
    pub fn icon_path(mut self, path: impl Into<PathBuf>) -> Self {
        self.icon_path = Some(path.into());
        self
    }

    /// 设置事件通道容量
    pub fn event_channel_capacity(mut self, capacity: usize) -> Self {
        self.event_channel_capacity = Some(capacity);
        self
    }

    /// 构建配置
    pub fn build(self) -> TrayConfig {
        let default = TrayConfig::default();
        TrayConfig {
            app_id: self.app_id.unwrap_or(default.app_id),
            tooltip: self.tooltip.unwrap_or(default.tooltip),
            icon_path: self.icon_path.or(default.icon_path),
            event_channel_capacity: self
                .event_channel_capacity
                .unwrap_or(default.event_channel_capacity),
        }
    }
}

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

    #[test]
    fn test_default_config() {
        let config = TrayConfig::default();
        assert_eq!(config.app_id, "unistore");
        assert_eq!(config.tooltip, "UniStore");
        assert!(config.icon_path.is_none());
        assert_eq!(config.event_channel_capacity, 64);
    }

    #[test]
    fn test_builder() {
        let config = TrayConfig::builder()
            .app_id("myapp")
            .tooltip("My Application")
            .icon_path("/path/to/icon.png")
            .event_channel_capacity(128)
            .build();

        assert_eq!(config.app_id, "myapp");
        assert_eq!(config.tooltip, "My Application");
        assert_eq!(
            config.icon_path,
            Some(PathBuf::from("/path/to/icon.png"))
        );
        assert_eq!(config.event_channel_capacity, 128);
    }

    #[test]
    fn test_partial_builder() {
        let config = TrayConfig::builder().tooltip("Custom Tooltip").build();

        assert_eq!(config.app_id, "unistore"); // 使用默认值
        assert_eq!(config.tooltip, "Custom Tooltip");
    }
}