open_lark/service/cloud_docs/bitable/v1/app_table_field/
mod.rs

1pub mod create;
2pub mod delete;
3pub mod list;
4pub mod types;
5pub mod update;
6
7use crate::core::config::Config;
8
9pub use create::*;
10pub use delete::*;
11pub use list::*;
12pub use types::*;
13pub use update::*;
14
15/// 字段服务
16pub struct AppTableFieldService {
17    config: Config,
18}
19
20impl AppTableFieldService {
21    pub fn new(config: Config) -> Self {
22        Self { config }
23    }
24
25    /// 新增字段
26    pub async fn create(
27        &self,
28        request: CreateFieldRequest,
29        option: Option<crate::core::req_option::RequestOption>,
30    ) -> crate::core::SDKResult<crate::core::api_resp::BaseResponse<CreateFieldResponse>> {
31        create::create_field(request, &self.config, option).await
32    }
33
34    /// 更新字段
35    pub async fn update(
36        &self,
37        request: UpdateFieldRequest,
38        option: Option<crate::core::req_option::RequestOption>,
39    ) -> crate::core::SDKResult<crate::core::api_resp::BaseResponse<UpdateFieldResponse>> {
40        update::update_field(request, &self.config, option).await
41    }
42
43    /// 列出字段
44    pub async fn list(
45        &self,
46        request: ListFieldRequest,
47        option: Option<crate::core::req_option::RequestOption>,
48    ) -> crate::core::SDKResult<crate::core::api_resp::BaseResponse<ListFieldResponse>> {
49        list::list_field(request, &self.config, option).await
50    }
51
52    /// 删除字段
53    pub async fn delete(
54        &self,
55        request: DeleteFieldRequest,
56        option: Option<crate::core::req_option::RequestOption>,
57    ) -> crate::core::SDKResult<crate::core::api_resp::BaseResponse<DeleteFieldResponse>> {
58        delete::delete_field(request, &self.config, option).await
59    }
60}
61
62#[cfg(test)]
63#[allow(unused_variables, unused_unsafe)]
64mod tests {
65    use super::*;
66    use crate::core::config::Config;
67
68    fn create_test_config() -> Config {
69        Config::default()
70    }
71
72    #[test]
73    fn test_app_table_field_service_creation() {
74        let config = create_test_config();
75        let service = AppTableFieldService::new(config.clone());
76
77        assert_eq!(service.config.app_id, config.app_id);
78        assert_eq!(service.config.app_secret, config.app_secret);
79    }
80
81    #[test]
82    fn test_app_table_field_service_with_custom_config() {
83        let config = Config::builder()
84            .app_id("field_app")
85            .app_secret("field_secret")
86            .req_timeout(std::time::Duration::from_millis(11000))
87            .base_url("https://field.api.com")
88            .build();
89
90        let service = AppTableFieldService::new(config.clone());
91
92        assert_eq!(service.config.app_id, "field_app");
93        assert_eq!(service.config.app_secret, "field_secret");
94        assert_eq!(service.config.base_url, "https://field.api.com");
95        assert_eq!(
96            service.config.req_timeout,
97            Some(std::time::Duration::from_millis(11000))
98        );
99    }
100
101    #[test]
102    fn test_app_table_field_service_config_independence() {
103        let config1 = Config::builder()
104            .app_id("field1")
105            .app_secret("secret1")
106            .build();
107        let config2 = Config::builder()
108            .app_id("field2")
109            .app_secret("secret2")
110            .build();
111
112        let service1 = AppTableFieldService::new(config1);
113        let service2 = AppTableFieldService::new(config2);
114
115        assert_eq!(service1.config.app_id, "field1");
116        assert_eq!(service2.config.app_id, "field2");
117        assert_ne!(service1.config.app_id, service2.config.app_id);
118    }
119
120    #[test]
121    fn test_app_table_field_service_memory_layout() {
122        let config = create_test_config();
123        let service = AppTableFieldService::new(config);
124
125        let service_ptr = std::ptr::addr_of!(service) as *const u8;
126        let config_ptr = std::ptr::addr_of!(service.config) as *const u8;
127
128        assert!(
129            !service_ptr.is_null(),
130            "Service should have valid memory address"
131        );
132        assert!(
133            !config_ptr.is_null(),
134            "Config should have valid memory address"
135        );
136    }
137
138    #[test]
139    fn test_app_table_field_service_with_different_configurations() {
140        let test_configs = vec![
141            Config::builder()
142                .app_id("field_basic")
143                .app_secret("basic_secret")
144                .build(),
145            Config::builder()
146                .app_id("field_timeout")
147                .app_secret("timeout_secret")
148                .req_timeout(std::time::Duration::from_millis(8500))
149                .build(),
150            Config::builder()
151                .app_id("field_custom")
152                .app_secret("custom_secret")
153                .base_url("https://custom.field.com")
154                .build(),
155            Config::builder()
156                .app_id("field_full")
157                .app_secret("full_secret")
158                .req_timeout(std::time::Duration::from_millis(18000))
159                .base_url("https://full.field.com")
160                .enable_token_cache(false)
161                .build(),
162        ];
163
164        for config in test_configs {
165            let service = AppTableFieldService::new(config.clone());
166
167            assert_eq!(service.config.app_id, config.app_id);
168            assert_eq!(service.config.app_secret, config.app_secret);
169            assert_eq!(service.config.base_url, config.base_url);
170            assert_eq!(service.config.req_timeout, config.req_timeout);
171        }
172    }
173
174    #[test]
175    fn test_app_table_field_service_multiple_instances() {
176        let config = create_test_config();
177        let service1 = AppTableFieldService::new(config.clone());
178        let service2 = AppTableFieldService::new(config.clone());
179
180        assert_eq!(service1.config.app_id, service2.config.app_id);
181        assert_eq!(service1.config.app_secret, service2.config.app_secret);
182
183        let ptr1 = std::ptr::addr_of!(service1) as *const u8;
184        let ptr2 = std::ptr::addr_of!(service2) as *const u8;
185        assert_ne!(ptr1, ptr2, "Services should be independent instances");
186    }
187
188    #[test]
189    fn test_app_table_field_service_config_cloning() {
190        let original_config = create_test_config();
191        let cloned_config = original_config.clone();
192
193        let service = AppTableFieldService::new(cloned_config);
194
195        assert_eq!(service.config.app_id, original_config.app_id);
196        assert_eq!(service.config.app_secret, original_config.app_secret);
197    }
198
199    #[test]
200    fn test_app_table_field_service_with_empty_config() {
201        let config = Config::default();
202        let service = AppTableFieldService::new(config);
203
204        assert_eq!(service.config.app_id, "");
205        assert_eq!(service.config.app_secret, "");
206    }
207
208    #[test]
209    fn test_app_table_field_service_with_unicode_config() {
210        let config = Config::builder()
211            .app_id("字段应用")
212            .app_secret("字段密钥")
213            .base_url("https://字段.com")
214            .build();
215        let service = AppTableFieldService::new(config);
216
217        assert_eq!(service.config.app_id, "字段应用");
218        assert_eq!(service.config.app_secret, "字段密钥");
219        assert_eq!(service.config.base_url, "https://字段.com");
220    }
221
222    #[test]
223    fn test_app_table_field_service_with_extreme_timeout() {
224        let config = Config::builder()
225            .app_id("field_extreme")
226            .app_secret("extreme_secret")
227            .req_timeout(std::time::Duration::from_secs(10800))
228            .build();
229        let service = AppTableFieldService::new(config);
230
231        assert_eq!(
232            service.config.req_timeout,
233            Some(std::time::Duration::from_secs(10800))
234        );
235    }
236
237    #[test]
238    fn test_app_table_field_service_concurrent_creation() {
239        let configs = vec![
240            Config::builder()
241                .app_id("field_concurrent_1")
242                .app_secret("secret_1")
243                .build(),
244            Config::builder()
245                .app_id("field_concurrent_2")
246                .app_secret("secret_2")
247                .build(),
248            Config::builder()
249                .app_id("field_concurrent_3")
250                .app_secret("secret_3")
251                .build(),
252        ];
253
254        let mut services = Vec::new();
255        for config in configs {
256            let service = AppTableFieldService::new(config);
257            services.push(service);
258        }
259
260        assert_eq!(services.len(), 3);
261
262        for (i, service1) in services.iter().enumerate() {
263            for service2 in services.iter().skip(i + 1) {
264                let ptr1 = std::ptr::addr_of!(*service1) as *const u8;
265                let ptr2 = std::ptr::addr_of!(*service2) as *const u8;
266                assert_ne!(ptr1, ptr2, "Services should be independent instances");
267            }
268        }
269    }
270
271    #[test]
272    fn test_app_table_field_service_construction_stability() {
273        for i in 0..100 {
274            let config = Config::builder()
275                .app_id(format!("field_app_{}", i))
276                .app_secret(format!("secret_{}", i))
277                .build();
278            let service = AppTableFieldService::new(config.clone());
279
280            assert_eq!(service.config.app_id, format!("field_app_{}", i));
281            assert_eq!(service.config.app_secret, format!("secret_{}", i));
282        }
283    }
284}