open_lark/service/search/
mod.rs1use crate::core::config::Config;
80
81pub mod v1;
83pub mod v2;
85
86pub struct SearchService {
120 pub v1: v1::V1,
122 pub v2: v2::V2,
124}
125
126impl SearchService {
127 pub fn new(config: Config) -> Self {
135 Self {
136 v1: v1::V1::new(config.clone()),
137 v2: v2::V2::new(config),
138 }
139 }
140
141 pub fn new_from_shared(shared: std::sync::Arc<Config>) -> Self {
143 Self {
144 v1: v1::V1::new(shared.as_ref().clone()),
145 v2: v2::V2::new(shared.as_ref().clone()),
146 }
147 }
148}
149
150#[cfg(test)]
151#[allow(unused_variables, unused_unsafe)]
152mod tests {
153 use super::*;
154 use crate::core::config::Config;
155
156 fn create_test_config() -> Config {
157 Config::default()
158 }
159
160 #[test]
161 fn test_search_service_creation() {
162 let config = create_test_config();
163 let search_service = SearchService::new(config);
164
165 }
167
168 #[test]
169 fn test_search_service_debug_trait() {
170 let config = create_test_config();
171 let search_service = SearchService::new(config);
172
173 }
175
176 #[test]
177 fn test_search_service_api_versions_independence() {
178 let config = create_test_config();
179 let search_service = SearchService::new(config);
180
181 let v1_ptr = std::ptr::addr_of!(search_service.v1) as *const u8;
183 let v2_ptr = std::ptr::addr_of!(search_service.v2) as *const u8;
184
185 assert_ne!(v1_ptr, v2_ptr, "API versions should be independent");
186 }
187
188 #[test]
189 fn test_search_service_with_custom_configurations() {
190 let test_configs = vec![
191 Config::builder()
192 .app_id("search_basic")
193 .app_secret("basic_secret")
194 .build(),
195 Config::builder()
196 .app_id("search_timeout")
197 .app_secret("timeout_secret")
198 .req_timeout(std::time::Duration::from_millis(25000))
199 .build(),
200 Config::builder()
201 .app_id("search_custom")
202 .app_secret("custom_secret")
203 .base_url("https://search.enterprise.com")
204 .build(),
205 Config::builder()
206 .app_id("search_full")
207 .app_secret("full_secret")
208 .req_timeout(std::time::Duration::from_millis(30000))
209 .base_url("https://full.search.com")
210 .enable_token_cache(false)
211 .build(),
212 ];
213
214 for config in test_configs {
215 let search_service = SearchService::new(config);
216
217 }
219 }
220
221 #[test]
222 fn test_search_service_multiple_instances() {
223 let config1 = create_test_config();
224 let config2 = Config::builder()
225 .app_id("search2")
226 .app_secret("secret2")
227 .build();
228
229 let search_service1 = SearchService::new(config1);
230 let search_service2 = SearchService::new(config2);
231
232 let service1_ptr = std::ptr::addr_of!(search_service1) as *const u8;
234 let service2_ptr = std::ptr::addr_of!(search_service2) as *const u8;
235
236 assert_ne!(
237 service1_ptr, service2_ptr,
238 "Services should be independent instances"
239 );
240
241 }
243
244 #[test]
245 fn test_search_service_config_cloning_behavior() {
246 let original_config = create_test_config();
247
248 let search_service1 = SearchService::new(original_config.clone());
250 let search_service2 = SearchService::new(original_config);
251
252 let service1_ptr = std::ptr::addr_of!(search_service1) as *const u8;
256 let service2_ptr = std::ptr::addr_of!(search_service2) as *const u8;
257 assert_ne!(service1_ptr, service2_ptr);
258 }
259
260 #[test]
261 fn test_search_service_v1_v2_api_access() {
262 let config = create_test_config();
263 let search_service = SearchService::new(config);
264
265 let v1_ptr = std::ptr::addr_of!(search_service.v1) as *const u8;
267 let v2_ptr = std::ptr::addr_of!(search_service.v2) as *const u8;
268
269 assert!(
270 !v1_ptr.is_null(),
271 "V1 service should be properly instantiated"
272 );
273 assert!(
274 !v2_ptr.is_null(),
275 "V2 service should be properly instantiated"
276 );
277 assert_ne!(
278 v1_ptr, v2_ptr,
279 "V1 and V2 services should be independent instances"
280 );
281 }
282
283 #[test]
284 fn test_search_service_with_various_configurations() {
285 let variations = vec![
286 (
287 "minimal",
288 Config::builder()
289 .app_id("minimal")
290 .app_secret("secret")
291 .build(),
292 ),
293 (
294 "with_timeout",
295 Config::builder()
296 .app_id("timeout")
297 .app_secret("secret")
298 .req_timeout(std::time::Duration::from_millis(35000))
299 .build(),
300 ),
301 (
302 "with_base_url",
303 Config::builder()
304 .app_id("base_url")
305 .app_secret("secret")
306 .base_url("https://test.search.api.com")
307 .build(),
308 ),
309 (
310 "full_featured",
311 Config::builder()
312 .app_id("full")
313 .app_secret("secret")
314 .req_timeout(std::time::Duration::from_millis(40000))
315 .base_url("https://full.test.search.api.com")
316 .enable_token_cache(true)
317 .build(),
318 ),
319 ];
320
321 let mut services = Vec::new();
322 for (name, config) in variations {
323 let service = SearchService::new(config);
324 services.push((name, service));
325 }
326
327 assert_eq!(services.len(), 4);
329
330 for (i, (_, service1)) in services.iter().enumerate() {
332 for (_, service2) in services.iter().skip(i + 1) {
333 let ptr1 = std::ptr::addr_of!(*service1) as *const u8;
334 let ptr2 = std::ptr::addr_of!(*service2) as *const u8;
335 assert_ne!(
336 ptr1, ptr2,
337 "Services with different configs should be independent"
338 );
339 }
340 }
341 }
342
343 #[test]
344 fn test_search_service_concurrent_creation() {
345 let configs = vec![
346 Config::builder()
347 .app_id("search_concurrent_1")
348 .app_secret("secret_1")
349 .build(),
350 Config::builder()
351 .app_id("search_concurrent_2")
352 .app_secret("secret_2")
353 .build(),
354 Config::builder()
355 .app_id("search_concurrent_3")
356 .app_secret("secret_3")
357 .build(),
358 ];
359
360 let mut services = Vec::new();
361 for config in configs {
362 let service = SearchService::new(config);
363 services.push(service);
364 }
365
366 assert_eq!(services.len(), 3);
368
369 for (i, service1) in services.iter().enumerate() {
371 for service2 in services.iter().skip(i + 1) {
372 let ptr1 = std::ptr::addr_of!(*service1) as *const u8;
373 let ptr2 = std::ptr::addr_of!(*service2) as *const u8;
374 assert_ne!(ptr1, ptr2, "Services should be independent instances");
375 }
376 }
377 }
378
379 #[test]
380 fn test_search_service_extreme_configurations() {
381 let extreme_configs = vec![
382 Config::builder()
384 .app_id("search_fast")
385 .app_secret("fast_secret")
386 .req_timeout(std::time::Duration::from_millis(50))
387 .build(),
388 Config::builder()
390 .app_id("search_slow")
391 .app_secret("slow_secret")
392 .req_timeout(std::time::Duration::from_secs(600))
393 .build(),
394 Config::builder()
396 .app_id("search_no_cache")
397 .app_secret("no_cache_secret")
398 .enable_token_cache(false)
399 .build(),
400 Config::builder()
402 .app_id("search_custom_base")
403 .app_secret("custom_base_secret")
404 .base_url("https://custom.search.api.endpoint")
405 .build(),
406 ];
407
408 for config in extreme_configs {
409 let search_service = SearchService::new(config);
410
411 let service_ptr = std::ptr::addr_of!(search_service) as *const u8;
413 assert!(
414 !service_ptr.is_null(),
415 "Service should be created with extreme config"
416 );
417 }
418 }
419
420 #[test]
421 fn test_search_service_api_version_structure() {
422 let config = create_test_config();
423 let search_service = SearchService::new(config);
424
425 let v1_offset = std::ptr::addr_of!(search_service.v1) as usize
427 - std::ptr::addr_of!(search_service) as usize;
428 let v2_offset = std::ptr::addr_of!(search_service.v2) as usize
429 - std::ptr::addr_of!(search_service) as usize;
430
431 assert_ne!(
433 v1_offset, v2_offset,
434 "V1 and V2 should occupy different memory positions"
435 );
436
437 assert!(v1_offset < 4096, "V1 offset should be reasonable");
439 assert!(v2_offset < 4096, "V2 offset should be reasonable");
440 }
441
442 #[test]
443 fn test_search_service_memory_consistency() {
444 let config = create_test_config();
445 let search_service = SearchService::new(config);
446
447 let service_ptr1 = std::ptr::addr_of!(search_service) as *const u8;
449 let service_ptr2 = std::ptr::addr_of!(search_service) as *const u8;
450
451 assert_eq!(
452 service_ptr1, service_ptr2,
453 "Service memory address should be consistent"
454 );
455
456 let v1_ptr1 = std::ptr::addr_of!(search_service.v1) as *const u8;
458 let v1_ptr2 = std::ptr::addr_of!(search_service.v1) as *const u8;
459 let v2_ptr1 = std::ptr::addr_of!(search_service.v2) as *const u8;
460 let v2_ptr2 = std::ptr::addr_of!(search_service.v2) as *const u8;
461
462 assert_eq!(
463 v1_ptr1, v1_ptr2,
464 "V1 API memory address should be consistent"
465 );
466 assert_eq!(
467 v2_ptr1, v2_ptr2,
468 "V2 API memory address should be consistent"
469 );
470 }
471
472 #[test]
473 fn test_search_service_v1_api_completeness() {
474 let config = create_test_config();
475 let search_service = SearchService::new(config);
476
477 let v1_ptr = std::ptr::addr_of!(search_service.v1) as *const u8;
479 assert!(!v1_ptr.is_null(), "V1 Search API should be instantiated");
480 }
481
482 #[test]
483 fn test_search_service_v2_api_completeness() {
484 let config = create_test_config();
485 let search_service = SearchService::new(config);
486
487 let v2_ptr = std::ptr::addr_of!(search_service.v2) as *const u8;
489 assert!(!v2_ptr.is_null(), "V2 Search API should be instantiated");
490 }
491
492 #[test]
493 fn test_search_service_config_independence() {
494 let config1 = Config::builder()
495 .app_id("search_app1")
496 .app_secret("search_secret1")
497 .build();
498 let config2 = Config::builder()
499 .app_id("search_app2")
500 .app_secret("search_secret2")
501 .build();
502
503 let search_service1 = SearchService::new(config1);
504 let search_service2 = SearchService::new(config2);
505
506 let service1_ptr = std::ptr::addr_of!(search_service1) as *const u8;
508 let service2_ptr = std::ptr::addr_of!(search_service2) as *const u8;
509
510 assert_ne!(
511 service1_ptr, service2_ptr,
512 "Services should be independent instances"
513 );
514
515 let v1_ptr1 = std::ptr::addr_of!(search_service1.v1) as *const u8;
517 let v1_ptr2 = std::ptr::addr_of!(search_service2.v1) as *const u8;
518 let v2_ptr1 = std::ptr::addr_of!(search_service1.v2) as *const u8;
519 let v2_ptr2 = std::ptr::addr_of!(search_service2.v2) as *const u8;
520
521 assert_ne!(v1_ptr1, v1_ptr2, "V1 services should be independent");
522 assert_ne!(v2_ptr1, v2_ptr2, "V2 services should be independent");
523 }
524
525 #[test]
526 fn test_search_service_configuration_scenarios() {
527 let empty_config = Config::default();
529 let search_service_empty = SearchService::new(empty_config);
530 let empty_ptr = std::ptr::addr_of!(search_service_empty) as *const u8;
531 assert!(!empty_ptr.is_null(), "Service should handle empty config");
532
533 let minimal_config = Config::builder().app_id("min").app_secret("sec").build();
535 let search_service_minimal = SearchService::new(minimal_config);
536 let minimal_ptr = std::ptr::addr_of!(search_service_minimal) as *const u8;
537 assert!(
538 !minimal_ptr.is_null(),
539 "Service should handle minimal config"
540 );
541
542 let unicode_config = Config::builder()
544 .app_id("搜索应用")
545 .app_secret("搜索密钥")
546 .base_url("https://搜索.com")
547 .build();
548 let search_service_unicode = SearchService::new(unicode_config);
549 let unicode_ptr = std::ptr::addr_of!(search_service_unicode) as *const u8;
550 assert!(
551 !unicode_ptr.is_null(),
552 "Service should handle Unicode config"
553 );
554 }
555}