open_lark/service/im/v1/message/
mod.rs1pub mod builders;
7pub mod content_types;
8pub mod list;
9pub mod send;
10pub mod types;
11
12pub use builders::{
14 CreateMessageRequest, CreateMessageRequestBody, CreateMessageRequestBodyBuilder,
15 CreateMessageRequestBuilder, UpdateMessageRequest, UpdateMessageRequestBuilder,
16};
17pub use content_types::*;
18pub use list::{ListMessageRequest, ListMessageRequestBuilder, ListMessageRespData};
19pub use types::{CreateMessageResp, ListMessageIterator, Message, SendMessageTrait};
20
21use crate::core::config::Config;
22use crate::impl_full_service;
23
24#[derive(Debug, Clone)]
34pub struct MessageService {
35 pub config: Config,
37}
38
39impl MessageService {
40 pub fn new(config: Config) -> Self {
42 Self { config }
43 }
44}
45
46impl_full_service!(MessageService, "im.message", "v1");
48
49#[cfg(test)]
50#[allow(unused_variables, unused_unsafe)]
51mod tests {
52 use super::*;
53 use crate::core::config::Config;
54 use crate::core::trait_system::Service;
55
56 fn create_test_config() -> Config {
57 Config::default()
58 }
59
60 #[test]
61 fn test_message_service_creation() {
62 let config = create_test_config();
63 let service = MessageService::new(config.clone());
64
65 assert_eq!(service.config.app_id, config.app_id);
66 assert_eq!(service.config.app_secret, config.app_secret);
67 assert_eq!(MessageService::service_name(), "im.message");
69 assert_eq!(MessageService::service_version(), "v1");
70 assert_eq!(service.config().app_id, config.app_id);
72 }
73
74 #[test]
75 fn test_message_service_with_custom_config() {
76 let config = Config::builder()
77 .app_id("message_app")
78 .app_secret("message_secret")
79 .req_timeout(std::time::Duration::from_millis(16000))
80 .base_url("https://message.api.com")
81 .build();
82
83 let service = MessageService::new(config.clone());
84
85 assert_eq!(service.config.app_id, "message_app");
86 assert_eq!(service.config.app_secret, "message_secret");
87 assert_eq!(service.config.base_url, "https://message.api.com");
88 assert_eq!(
89 service.config.req_timeout,
90 Some(std::time::Duration::from_millis(16000))
91 );
92 }
93
94 #[test]
95 fn test_message_service_config_independence() {
96 let config1 = Config::builder()
97 .app_id("message1")
98 .app_secret("secret1")
99 .build();
100 let config2 = Config::builder()
101 .app_id("message2")
102 .app_secret("secret2")
103 .build();
104
105 let service1 = MessageService::new(config1);
106 let service2 = MessageService::new(config2);
107
108 assert_eq!(service1.config.app_id, "message1");
109 assert_eq!(service2.config.app_id, "message2");
110 assert_ne!(service1.config.app_id, service2.config.app_id);
111 }
112
113 #[test]
114 fn test_message_service_memory_layout() {
115 let config = create_test_config();
116 let service = MessageService::new(config);
117
118 let service_ptr = std::ptr::addr_of!(service) as *const u8;
119 let config_ptr = std::ptr::addr_of!(service.config) as *const u8;
120
121 assert!(
122 !service_ptr.is_null(),
123 "Service should have valid memory address"
124 );
125 assert!(
126 !config_ptr.is_null(),
127 "Config should have valid memory address"
128 );
129 }
130
131 #[test]
132 fn test_message_service_with_different_configurations() {
133 let test_configs = vec![
134 Config::builder()
135 .app_id("message_basic")
136 .app_secret("basic_secret")
137 .build(),
138 Config::builder()
139 .app_id("message_timeout")
140 .app_secret("timeout_secret")
141 .req_timeout(std::time::Duration::from_millis(13500))
142 .build(),
143 Config::builder()
144 .app_id("message_custom")
145 .app_secret("custom_secret")
146 .base_url("https://custom.message.com")
147 .build(),
148 Config::builder()
149 .app_id("message_full")
150 .app_secret("full_secret")
151 .req_timeout(std::time::Duration::from_millis(23000))
152 .base_url("https://full.message.com")
153 .enable_token_cache(false)
154 .build(),
155 ];
156
157 for config in test_configs {
158 let service = MessageService::new(config.clone());
159
160 assert_eq!(service.config.app_id, config.app_id);
161 assert_eq!(service.config.app_secret, config.app_secret);
162 assert_eq!(service.config.base_url, config.base_url);
163 assert_eq!(service.config.req_timeout, config.req_timeout);
164 }
165 }
166
167 #[test]
168 fn test_message_service_multiple_instances() {
169 let config = create_test_config();
170 let service1 = MessageService::new(config.clone());
171 let service2 = MessageService::new(config.clone());
172
173 assert_eq!(service1.config.app_id, service2.config.app_id);
174 assert_eq!(service1.config.app_secret, service2.config.app_secret);
175
176 let ptr1 = std::ptr::addr_of!(service1) as *const u8;
177 let ptr2 = std::ptr::addr_of!(service2) as *const u8;
178 assert_ne!(ptr1, ptr2, "Services should be independent instances");
179 }
180
181 #[test]
182 fn test_message_service_config_cloning() {
183 let original_config = create_test_config();
184 let cloned_config = original_config.clone();
185
186 let service = MessageService::new(cloned_config);
187
188 assert_eq!(service.config.app_id, original_config.app_id);
189 assert_eq!(service.config.app_secret, original_config.app_secret);
190 }
191
192 #[test]
193 fn test_message_service_with_empty_config() {
194 let config = Config::default();
195 let service = MessageService::new(config);
196
197 assert_eq!(service.config.app_id, "");
198 assert_eq!(service.config.app_secret, "");
199 }
200
201 #[test]
202 fn test_message_service_with_unicode_config() {
203 let config = Config::builder()
204 .app_id("消息应用")
205 .app_secret("消息密钥")
206 .base_url("https://消息.com")
207 .build();
208 let service = MessageService::new(config);
209
210 assert_eq!(service.config.app_id, "消息应用");
211 assert_eq!(service.config.app_secret, "消息密钥");
212 assert_eq!(service.config.base_url, "https://消息.com");
213 }
214
215 #[test]
216 fn test_message_service_with_extreme_timeout() {
217 let config = Config::builder()
218 .app_id("message_extreme")
219 .app_secret("extreme_secret")
220 .req_timeout(std::time::Duration::from_secs(10800))
221 .build();
222 let service = MessageService::new(config);
223
224 assert_eq!(
225 service.config.req_timeout,
226 Some(std::time::Duration::from_secs(10800))
227 );
228 }
229
230 #[test]
231 fn test_message_service_concurrent_creation() {
232 let configs = vec![
233 Config::builder()
234 .app_id("message_concurrent_1")
235 .app_secret("secret_1")
236 .build(),
237 Config::builder()
238 .app_id("message_concurrent_2")
239 .app_secret("secret_2")
240 .build(),
241 Config::builder()
242 .app_id("message_concurrent_3")
243 .app_secret("secret_3")
244 .build(),
245 ];
246
247 let mut services = Vec::new();
248 for config in configs {
249 let service = MessageService::new(config);
250 services.push(service);
251 }
252
253 assert_eq!(services.len(), 3);
254
255 for (i, service1) in services.iter().enumerate() {
256 for service2 in services.iter().skip(i + 1) {
257 let ptr1 = std::ptr::addr_of!(*service1) as *const u8;
258 let ptr2 = std::ptr::addr_of!(*service2) as *const u8;
259 assert_ne!(ptr1, ptr2, "Services should be independent instances");
260 }
261 }
262 }
263
264 #[test]
265 fn test_message_service_debug_trait() {
266 let config = create_test_config();
267 let service = MessageService::new(config);
268
269 let debug_output = format!("{:?}", service);
270 assert!(debug_output.contains("MessageService"));
271 assert!(debug_output.contains("config"));
272 }
273
274 #[test]
275 fn test_message_service_clone_trait() {
276 let config = create_test_config();
277 let service = MessageService::new(config);
278 let cloned_service = service.clone();
279
280 assert_eq!(service.config.app_id, cloned_service.config.app_id);
281 assert_eq!(service.config.app_secret, cloned_service.config.app_secret);
282
283 let ptr1 = std::ptr::addr_of!(service) as *const u8;
284 let ptr2 = std::ptr::addr_of!(cloned_service) as *const u8;
285 assert_ne!(ptr1, ptr2, "Cloned service should be a different instance");
286 }
287}