Skip to main content

openlark_client/traits/
client.rs

1//! OpenLark Client 核心特征
2//!
3//! 定义客户端的统一接口和行为
4
5use crate::Config;
6use std::time::Duration;
7
8/// 🚀 OpenLark客户端核心特征
9///
10/// 所有OpenLark客户端实现都应该实现此特征
11///
12/// # 特性要求
13/// - 异步支持:所有操作都是异步的
14/// - 线程安全:客户端可以跨线程安全使用
15/// - 配置访问:可以访问客户端配置
16/// - 错误处理:统一的错误处理机制
17pub trait LarkClient: Send + Sync {
18    /// 🔧 获取客户端配置
19    fn config(&self) -> &Config;
20
21    /// ✅ 检查客户端是否已正确配置
22    ///
23    /// # 返回值
24    /// 返回true如果app_id和app_secret都不为空
25    fn is_configured(&self) -> bool {
26        !self.config().app_id.is_empty() && !self.config().app_secret.is_empty()
27    }
28
29    /// 🔍 获取应用ID
30    fn app_id(&self) -> &str {
31        &self.config().app_id
32    }
33
34    /// 🔑 获取应用密钥
35    fn app_secret(&self) -> &str {
36        &self.config().app_secret
37    }
38
39    /// 🌐 获取API基础URL
40    fn base_url(&self) -> &str {
41        &self.config().base_url
42    }
43
44    /// ⏱️ 获取请求超时时间
45    fn timeout(&self) -> Duration {
46        self.config().timeout
47    }
48
49    /// 🔄 获取重试次数
50    fn retry_count(&self) -> u32 {
51        self.config().retry_count
52    }
53
54    /// 📝 检查是否启用了日志
55    fn is_log_enabled(&self) -> bool {
56        self.config().enable_log
57    }
58}
59
60#[cfg(test)]
61#[allow(unused_imports)]
62mod tests {
63    use super::*;
64    use std::time::Duration;
65
66    struct TestClient {
67        config: Config,
68    }
69
70    impl LarkClient for TestClient {
71        fn config(&self) -> &Config {
72            &self.config
73        }
74    }
75
76    #[test]
77    fn test_lark_client_basic_methods() {
78        let config = Config {
79            app_id: "test_app_id".to_string(),
80            app_secret: "test_app_secret".to_string(),
81            app_type: openlark_core::constants::AppType::SelfBuild,
82            enable_token_cache: true,
83            base_url: "https://test.feishu.cn".to_string(),
84            allow_custom_base_url: false,
85            timeout: Duration::from_secs(30),
86            retry_count: 3,
87            enable_log: true,
88            headers: std::collections::HashMap::new(),
89            max_response_size: 100 * 1024 * 1024,
90            core_config: None,
91        };
92
93        let client = TestClient { config };
94
95        assert_eq!(client.app_id(), "test_app_id");
96        assert_eq!(client.app_secret(), "test_app_secret");
97        assert_eq!(client.base_url(), "https://test.feishu.cn");
98        assert_eq!(client.timeout(), Duration::from_secs(30));
99        assert_eq!(client.retry_count(), 3);
100        assert!(client.is_log_enabled());
101        assert!(client.is_configured());
102    }
103
104    #[test]
105    fn test_not_configured_client() {
106        let config = Config {
107            app_id: String::new(),
108            app_secret: String::new(),
109            ..Default::default()
110        };
111
112        let client = TestClient { config };
113        assert!(!client.is_configured());
114    }
115}