Skip to main content

openlark_docs/common/
api_endpoints.rs

1//! API端点定义(类型安全枚举系统)
2//!
3//! 本模块提供基于枚举的 API 端点定义,用于生产代码中的类型安全调用。
4//!
5//! # 使用场景
6//!
7//! ## 生产代码(推荐)
8//! 使用枚举端点获得编译时类型检查和动态 URL 生成能力:
9//! ```rust
10//! use openlark_docs::common::api_endpoints::BitableApiV1;
11//!
12//! let app_token = "app_token".to_string();
13//! let table_id = "table_id".to_string();
14//! let endpoint = BitableApiV1::RecordCreate(app_token, table_id);
15//! let url = endpoint.to_url(); // 类型安全,动态生成
16//! assert!(url.contains("/open-apis/bitable/v1/"));
17//! ```
18//!
19//! # 特性
20//! - ✅ **类型安全**:编译时验证参数
21//! - ✅ **动态生成**:支持参数化 URL
22//! - ✅ **易于维护**:集中管理端点定义
23//! - ✅ **避免错误**:消除字符串拼接错误
24//!
25//! # 与常量端点系统的关系
26//!
27//! 本模块与 `endpoints/mod.rs` 中的常量端点系统配合使用:
28//! - **枚举端点**:用于生产代码(推荐)
29//! - **常量端点**:用于测试和文档示例
30//!
31//! 不建议混合使用两个系统,应根据场景选择合适的端点方式。
32
33/// Base API V2 端点枚举
34#[derive(Debug, Clone, PartialEq)]
35pub enum BaseApiV2 {
36    /// 新增自定义角色
37    RoleCreate(String),
38    /// 更新自定义角色
39    RoleUpdate(String, String),
40    /// 列出自定义角色
41    RoleList(String),
42}
43
44impl BaseApiV2 {
45    /// 生成对应的 URL
46    pub fn to_url(&self) -> String {
47        match self {
48            BaseApiV2::RoleCreate(app_token) => {
49                format!("/open-apis/base/v2/apps/{app_token}/roles")
50            }
51            BaseApiV2::RoleUpdate(app_token, role_id) => {
52                format!("/open-apis/base/v2/apps/{app_token}/roles/{role_id}")
53            }
54            BaseApiV2::RoleList(app_token) => {
55                format!("/open-apis/base/v2/apps/{app_token}/roles")
56            }
57        }
58    }
59}
60
61/// Bitable API V1 端点枚举
62#[derive(Debug, Clone, PartialEq)]
63pub enum BitableApiV1 {
64    /// App管理相关
65    AppCreate,
66    /// 公开项说明。
67    AppCopy(String),
68    /// 公开项说明。
69    AppGet(String),
70    /// 公开项说明。
71    AppUpdate(String),
72    /// 公开项说明。
73    DashboardList(String),
74    /// 公开项说明。
75    DashboardCopy(String, String),
76    /// 自动化流程
77    BlockWorkflowList(String),
78    /// 公开项说明。
79    WorkflowList(String),
80    /// 公开项说明。
81    WorkflowUpdate(String, String),
82
83    /// 表格管理相关
84    TableCreate(String),
85    /// 公开项说明。
86    TableBatchCreate(String),
87    /// 公开项说明。
88    TableUpdate(String, String),
89    /// 公开项说明。
90    TableDelete(String, String),
91    /// 公开项说明。
92    TableBatchDelete(String),
93    /// 公开项说明。
94    TableGet(String, String),
95    /// 公开项说明。
96    TableList(String),
97    /// 公开项说明。
98    TablePatch(String, String),
99
100    /// 字段管理相关
101    FieldCreate(String, String),
102    /// 公开项说明。
103    FieldGroupCreate(String, String),
104    /// 公开项说明。
105    FieldUpdate(String, String, String),
106    /// 公开项说明。
107    FieldDelete(String, String, String),
108    /// 公开项说明。
109    FieldList(String, String),
110
111    /// 视图管理相关
112    ViewCreate(String, String),
113    /// 公开项说明。
114    ViewUpdate(String, String, String),
115    /// 公开项说明。
116    ViewDelete(String, String, String),
117    /// 公开项说明。
118    ViewGet(String, String, String),
119    /// 公开项说明。
120    ViewList(String, String),
121    /// 公开项说明。
122    ViewPatch(String, String, String),
123
124    /// 记录管理相关
125    RecordCreate(String, String),
126    /// 公开项说明。
127    RecordBatchCreate(String, String),
128    /// 公开项说明。
129    RecordGet(String, String, String),
130    /// 公开项说明。
131    RecordBatchGet(String, String),
132    /// 公开项说明。
133    RecordUpdate(String, String, String),
134    /// 公开项说明。
135    RecordBatchUpdate(String, String),
136    /// 公开项说明。
137    RecordDelete(String, String, String),
138    /// 公开项说明。
139    RecordBatchDelete(String, String),
140    /// 公开项说明。
141    RecordList(String, String),
142    /// 公开项说明。
143    RecordSearch(String, String),
144
145    /// 表单管理相关
146    FormGet(String, String, String),
147    /// 公开项说明。
148    FormPatch(String, String, String),
149    /// 公开项说明。
150    FormUpgrade(String, String, String),
151    /// 公开项说明。
152    FormFieldList(String, String, String),
153    /// 公开项说明。
154    FormFieldPatch(String, String, String, String),
155
156    /// 权限管理相关
157    RoleCreate(String),
158    /// 公开项说明。
159    RoleUpdate(String, String),
160    /// 公开项说明。
161    RoleDelete(String, String),
162    /// 公开项说明。
163    RoleList(String),
164    /// 公开项说明。
165    RoleMemberCreate(String, String),
166    /// 公开项说明。
167    RoleMemberBatchCreate(String, String),
168    /// 公开项说明。
169    RoleMemberDelete(String, String, String),
170    /// 公开项说明。
171    RoleMemberBatchDelete(String, String),
172    /// 公开项说明。
173    RoleMemberList(String, String),
174}
175
176impl BitableApiV1 {
177    /// 生成对应的 URL
178    pub fn to_url(&self) -> String {
179        match self {
180            // App管理
181            BitableApiV1::AppCreate => "/open-apis/bitable/v1/apps".to_string(),
182            BitableApiV1::AppCopy(app_token) => {
183                format!("/open-apis/bitable/v1/apps/{app_token}/copy")
184            }
185            BitableApiV1::AppGet(app_token) => {
186                format!("/open-apis/bitable/v1/apps/{app_token}")
187            }
188            BitableApiV1::AppUpdate(app_token) => {
189                format!("/open-apis/bitable/v1/apps/{app_token}")
190            }
191            BitableApiV1::DashboardList(app_token) => {
192                format!("/open-apis/bitable/v1/apps/{app_token}/dashboards")
193            }
194            BitableApiV1::DashboardCopy(app_token, block_id) => {
195                format!("/open-apis/bitable/v1/apps/{app_token}/dashboards/{block_id}/copy")
196            }
197            BitableApiV1::BlockWorkflowList(app_token) => {
198                format!("/open-apis/bitable/v1/apps/{app_token}/block_workflows")
199            }
200            BitableApiV1::WorkflowList(app_token) => {
201                format!("/open-apis/bitable/v1/apps/{app_token}/workflows")
202            }
203            BitableApiV1::WorkflowUpdate(app_token, workflow_id) => {
204                format!("/open-apis/bitable/v1/apps/{app_token}/workflows/{workflow_id}")
205            }
206
207            // 表格管理
208            BitableApiV1::TableCreate(app_token) => {
209                format!("/open-apis/bitable/v1/apps/{app_token}/tables")
210            }
211            BitableApiV1::TableBatchCreate(app_token) => {
212                format!("/open-apis/bitable/v1/apps/{app_token}/tables/batch_create")
213            }
214            BitableApiV1::TableUpdate(app_token, table_id) => {
215                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}")
216            }
217            BitableApiV1::TableDelete(app_token, table_id) => {
218                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}")
219            }
220            BitableApiV1::TableBatchDelete(app_token) => {
221                format!("/open-apis/bitable/v1/apps/{app_token}/tables/batch_delete")
222            }
223            BitableApiV1::TableGet(app_token, table_id) => {
224                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}")
225            }
226            BitableApiV1::TableList(app_token) => {
227                format!("/open-apis/bitable/v1/apps/{app_token}/tables")
228            }
229            BitableApiV1::TablePatch(app_token, table_id) => {
230                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}")
231            }
232
233            // 字段管理
234            BitableApiV1::FieldCreate(app_token, table_id) => {
235                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/fields")
236            }
237            BitableApiV1::FieldGroupCreate(app_token, table_id) => {
238                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/field_groups")
239            }
240            BitableApiV1::FieldUpdate(app_token, table_id, field_id) => {
241                format!(
242                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/fields/{field_id}"
243                )
244            }
245            BitableApiV1::FieldDelete(app_token, table_id, field_id) => {
246                format!(
247                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/fields/{field_id}"
248                )
249            }
250            BitableApiV1::FieldList(app_token, table_id) => {
251                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/fields")
252            }
253
254            // 视图管理
255            BitableApiV1::ViewCreate(app_token, table_id) => {
256                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/views")
257            }
258            BitableApiV1::ViewUpdate(app_token, table_id, view_id) => {
259                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/views/{view_id}")
260            }
261            BitableApiV1::ViewDelete(app_token, table_id, view_id) => {
262                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/views/{view_id}")
263            }
264            BitableApiV1::ViewGet(app_token, table_id, view_id) => {
265                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/views/{view_id}")
266            }
267            BitableApiV1::ViewList(app_token, table_id) => {
268                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/views")
269            }
270            BitableApiV1::ViewPatch(app_token, table_id, view_id) => {
271                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/views/{view_id}")
272            }
273
274            // 记录管理
275            BitableApiV1::RecordCreate(app_token, table_id) => {
276                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records")
277            }
278            BitableApiV1::RecordBatchCreate(app_token, table_id) => {
279                format!(
280                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_create"
281                )
282            }
283            BitableApiV1::RecordGet(app_token, table_id, record_id) => {
284                format!(
285                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}"
286                )
287            }
288            BitableApiV1::RecordBatchGet(app_token, table_id) => {
289                format!(
290                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_get"
291                )
292            }
293            BitableApiV1::RecordUpdate(app_token, table_id, record_id) => {
294                format!(
295                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}"
296                )
297            }
298            BitableApiV1::RecordBatchUpdate(app_token, table_id) => {
299                format!(
300                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_update"
301                )
302            }
303            BitableApiV1::RecordDelete(app_token, table_id, record_id) => {
304                format!(
305                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}"
306                )
307            }
308            BitableApiV1::RecordBatchDelete(app_token, table_id) => {
309                format!(
310                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_delete"
311                )
312            }
313            BitableApiV1::RecordList(app_token, table_id) => {
314                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records")
315            }
316            BitableApiV1::RecordSearch(app_token, table_id) => {
317                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/search")
318            }
319
320            // 表单管理
321            BitableApiV1::FormGet(app_token, table_id, form_id) => {
322                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/forms/{form_id}")
323            }
324            BitableApiV1::FormPatch(app_token, table_id, form_id) => {
325                format!("/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/forms/{form_id}")
326            }
327            BitableApiV1::FormUpgrade(app_token, table_id, form_id) => {
328                format!(
329                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/forms/{form_id}/upgrade"
330                )
331            }
332            BitableApiV1::FormFieldList(app_token, table_id, form_id) => {
333                format!(
334                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/forms/{form_id}/fields"
335                )
336            }
337            BitableApiV1::FormFieldPatch(app_token, table_id, form_id, field_id) => {
338                format!(
339                    "/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/forms/{form_id}/fields/{field_id}"
340                )
341            }
342
343            // 权限管理
344            BitableApiV1::RoleCreate(app_token) => {
345                format!("/open-apis/bitable/v1/apps/{app_token}/roles")
346            }
347            BitableApiV1::RoleUpdate(app_token, role_id) => {
348                format!("/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}")
349            }
350            BitableApiV1::RoleDelete(app_token, role_id) => {
351                format!("/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}")
352            }
353            BitableApiV1::RoleList(app_token) => {
354                format!("/open-apis/bitable/v1/apps/{app_token}/roles")
355            }
356            BitableApiV1::RoleMemberCreate(app_token, role_id) => {
357                format!("/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}/members")
358            }
359            BitableApiV1::RoleMemberBatchCreate(app_token, role_id) => {
360                format!(
361                    "/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}/members/batch_create"
362                )
363            }
364            BitableApiV1::RoleMemberDelete(app_token, role_id, member_id) => {
365                format!(
366                    "/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}/members/{member_id}"
367                )
368            }
369            BitableApiV1::RoleMemberBatchDelete(app_token, role_id) => {
370                format!(
371                    "/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}/members/batch_delete"
372                )
373            }
374            BitableApiV1::RoleMemberList(app_token, role_id) => {
375                format!("/open-apis/bitable/v1/apps/{app_token}/roles/{role_id}/members")
376            }
377        }
378    }
379}
380
381/// Minutes API V1 端点枚举
382#[derive(Debug, Clone, PartialEq)]
383pub enum MinutesApiV1 {
384    /// 获取妙记信息
385    Get(String),
386    /// 订阅妙记变更事件
387    Subscription,
388    /// 取消订阅妙记变更事件
389    Unsubscription,
390    /// 下载妙记音视频文件
391    MediaGet(String),
392    /// 导出妙记文字记录
393    TranscriptGet(String),
394    /// 获取妙记统计数据
395    StatisticsGet(String),
396}
397
398impl MinutesApiV1 {
399    /// 生成对应的 URL
400    pub fn to_url(&self) -> String {
401        match self {
402            MinutesApiV1::Get(minute_token) => {
403                format!("/open-apis/minutes/v1/minutes/{minute_token}")
404            }
405            MinutesApiV1::Subscription => "/open-apis/minutes/v1/minutes/subscription".to_string(),
406            MinutesApiV1::Unsubscription => {
407                "/open-apis/minutes/v1/minutes/unsubscription".to_string()
408            }
409            MinutesApiV1::MediaGet(minute_token) => {
410                format!("/open-apis/minutes/v1/minutes/{minute_token}/media")
411            }
412            MinutesApiV1::TranscriptGet(minute_token) => {
413                format!("/open-apis/minutes/v1/minutes/{minute_token}/transcript")
414            }
415            MinutesApiV1::StatisticsGet(minute_token) => {
416                format!("/open-apis/minutes/v1/minutes/{minute_token}/statistics")
417            }
418        }
419    }
420}
421
422/// Wiki API V1 端点枚举
423#[derive(Debug, Clone, PartialEq)]
424pub enum WikiApiV1 {
425    /// 搜索Wiki
426    NodeSearch,
427}
428
429impl WikiApiV1 {
430    /// 生成对应的 URL
431    pub fn to_url(&self) -> String {
432        match self {
433            WikiApiV1::NodeSearch => "/open-apis/wiki/v1/nodes/search".to_string(),
434        }
435    }
436}
437
438/// Docs API V1 端点枚举
439#[derive(Debug, Clone, PartialEq)]
440pub enum DocsApiV1 {
441    /// 获取云文档内容
442    ContentGet,
443}
444
445impl DocsApiV1 {
446    /// 生成对应的 URL
447    pub fn to_url(&self) -> String {
448        match self {
449            DocsApiV1::ContentGet => "/open-apis/docs/v1/content".to_string(),
450        }
451    }
452}
453
454/// Docx API V1 端点枚举
455#[derive(Debug, Clone, PartialEq)]
456pub enum DocxApiV1 {
457    // 群公告相关API (7个)
458    /// 获取群公告基本信息
459    ChatAnnouncementGet(String),
460    /// 获取群公告所有块
461    ChatAnnouncementBlockList(String),
462    /// 在群公告中创建块
463    ChatAnnouncementBlockChildrenCreate(String, String),
464    /// 批量更新群公告块的内容
465    ChatAnnouncementBlockBatchUpdate(String),
466    /// 获取群公告块的内容
467    ChatAnnouncementBlockGet(String, String),
468    /// 获取所有子块
469    ChatAnnouncementBlockChildrenGet(String, String),
470    /// 删除群公告中的块
471    ChatAnnouncementBlockChildrenBatchDelete(String, String),
472
473    // 文档相关API (12个)
474    /// 创建文档
475    DocumentCreate,
476    /// 获取文档基本信息
477    DocumentGet(String),
478    /// 获取文档纯文本内容
479    DocumentRawContent(String),
480    /// 获取文档所有块
481    DocumentBlockList(String),
482    /// 创建块
483    DocumentBlockChildrenCreate(String, String),
484    /// 创建嵌套块
485    DocumentBlockDescendantCreate(String, String),
486    /// 更新块的内容
487    DocumentBlockPatch(String, String),
488    /// 获取块的内容
489    DocumentBlockGet(String, String),
490    /// 批量更新块的内容
491    DocumentBlockBatchUpdate(String),
492    /// 获取所有子块
493    DocumentBlockChildrenGet(String, String),
494    /// 删除块
495    DocumentBlockChildrenBatchDelete(String, String),
496    /// Markdown/HTML 内容转换为文档块
497    DocumentConvert,
498}
499
500impl DocxApiV1 {
501    /// 生成对应的 URL
502    pub fn to_url(&self) -> String {
503        match self {
504            // 群公告相关API (7个)
505            DocxApiV1::ChatAnnouncementGet(chat_id) => {
506                format!("/open-apis/docx/v1/chats/{chat_id}/announcement")
507            }
508            DocxApiV1::ChatAnnouncementBlockList(chat_id) => {
509                format!("/open-apis/docx/v1/chats/{chat_id}/announcement/blocks")
510            }
511            DocxApiV1::ChatAnnouncementBlockChildrenCreate(chat_id, block_id) => {
512                format!(
513                    "/open-apis/docx/v1/chats/{chat_id}/announcement/blocks/{block_id}/children"
514                )
515            }
516            DocxApiV1::ChatAnnouncementBlockBatchUpdate(chat_id) => {
517                format!("/open-apis/docx/v1/chats/{chat_id}/announcement/blocks/batch_update")
518            }
519            DocxApiV1::ChatAnnouncementBlockGet(chat_id, block_id) => {
520                format!("/open-apis/docx/v1/chats/{chat_id}/announcement/blocks/{block_id}")
521            }
522            DocxApiV1::ChatAnnouncementBlockChildrenGet(chat_id, block_id) => {
523                format!(
524                    "/open-apis/docx/v1/chats/{chat_id}/announcement/blocks/{block_id}/children"
525                )
526            }
527            DocxApiV1::ChatAnnouncementBlockChildrenBatchDelete(chat_id, block_id) => {
528                format!(
529                    "/open-apis/docx/v1/chats/{chat_id}/announcement/blocks/{block_id}/children/batch_delete"
530                )
531            }
532
533            // 文档相关API (12个)
534            DocxApiV1::DocumentCreate => "/open-apis/docx/v1/documents".to_string(),
535            DocxApiV1::DocumentGet(document_id) => {
536                format!("/open-apis/docx/v1/documents/{document_id}")
537            }
538            DocxApiV1::DocumentRawContent(document_id) => {
539                format!("/open-apis/docx/v1/documents/{document_id}/raw_content")
540            }
541            DocxApiV1::DocumentBlockList(document_id) => {
542                format!("/open-apis/docx/v1/documents/{document_id}/blocks")
543            }
544            DocxApiV1::DocumentBlockChildrenCreate(document_id, block_id) => {
545                format!("/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}/children")
546            }
547            DocxApiV1::DocumentBlockDescendantCreate(document_id, block_id) => {
548                format!("/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}/descendant")
549            }
550            DocxApiV1::DocumentBlockPatch(document_id, block_id) => {
551                format!("/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}")
552            }
553            DocxApiV1::DocumentBlockGet(document_id, block_id) => {
554                format!("/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}")
555            }
556            DocxApiV1::DocumentBlockBatchUpdate(document_id) => {
557                format!("/open-apis/docx/v1/documents/{document_id}/blocks/batch_update")
558            }
559            DocxApiV1::DocumentBlockChildrenGet(document_id, block_id) => {
560                format!("/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}/children")
561            }
562            DocxApiV1::DocumentBlockChildrenBatchDelete(document_id, block_id) => {
563                format!(
564                    "/open-apis/docx/v1/documents/{document_id}/blocks/{block_id}/children/batch_delete"
565                )
566            }
567            // 注意:该接口虽然归类在 docx-v1 文档下,但实际 HTTP URL 不包含 /v1
568            DocxApiV1::DocumentConvert => "/open-apis/docx/documents/blocks/convert".to_string(),
569        }
570    }
571}
572
573/// Wiki API V2 端点枚举
574#[derive(Debug, Clone, PartialEq)]
575pub enum WikiApiV2 {
576    /// 获取知识空间列表
577    SpaceList,
578    /// 获取知识空间信息
579    SpaceGet(String),
580    /// 创建知识空间
581    SpaceCreate,
582    /// 更新知识空间设置
583    SpaceSettingUpdate(String),
584    /// 获取知识空间节点信息
585    SpaceGetNode,
586    /// 获取知识空间子节点列表
587    SpaceNodeList(String),
588    /// 创建知识空间节点
589    SpaceNodeCreate(String),
590    /// 获取知识空间成员列表
591    SpaceMemberList(String),
592    /// 添加知识空间成员
593    SpaceMemberCreate(String),
594    /// 删除知识空间成员
595    SpaceMemberDelete(String, String), // space_id, member_id
596    /// 移动知识空间节点
597    SpaceNodeMove(String, String),
598    /// 更新知识空间节点标题
599    SpaceNodeUpdateTitle(String, String),
600    /// 创建知识空间节点副本
601    SpaceNodeCopy(String, String),
602    /// 移动云空间文档至知识空间
603    SpaceNodeMoveDocsToWiki(String),
604    /// 获取任务结果
605    TaskGet(String),
606}
607
608impl WikiApiV2 {
609    /// 生成对应的 URL
610    pub fn to_url(&self) -> String {
611        match self {
612            WikiApiV2::SpaceList => "/open-apis/wiki/v2/spaces".to_string(),
613            WikiApiV2::SpaceGet(space_id) => {
614                format!("/open-apis/wiki/v2/spaces/{space_id}")
615            }
616            WikiApiV2::SpaceCreate => "/open-apis/wiki/v2/spaces".to_string(),
617            WikiApiV2::SpaceSettingUpdate(space_id) => {
618                format!("/open-apis/wiki/v2/spaces/{space_id}/setting")
619            }
620            WikiApiV2::SpaceGetNode => "/open-apis/wiki/v2/spaces/get_node".to_string(),
621            WikiApiV2::SpaceNodeList(space_id) => {
622                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes")
623            }
624            WikiApiV2::SpaceNodeCreate(space_id) => {
625                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes")
626            }
627            WikiApiV2::SpaceMemberList(space_id) => {
628                format!("/open-apis/wiki/v2/spaces/{space_id}/members")
629            }
630            WikiApiV2::SpaceMemberCreate(space_id) => {
631                format!("/open-apis/wiki/v2/spaces/{space_id}/members")
632            }
633            WikiApiV2::SpaceMemberDelete(space_id, member_id) => {
634                format!("/open-apis/wiki/v2/spaces/{space_id}/members/{member_id}")
635            }
636            WikiApiV2::SpaceNodeMove(space_id, node_token) => {
637                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/{node_token}/move")
638            }
639            WikiApiV2::SpaceNodeUpdateTitle(space_id, node_token) => {
640                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/{node_token}/update_title")
641            }
642            WikiApiV2::SpaceNodeCopy(space_id, node_token) => {
643                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/{node_token}/copy")
644            }
645            WikiApiV2::SpaceNodeMoveDocsToWiki(space_id) => {
646                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/move_docs_to_wiki")
647            }
648            WikiApiV2::TaskGet(task_id) => {
649                format!("/open-apis/wiki/v2/tasks/{task_id}")
650            }
651        }
652    }
653}
654
655/// CCM Doc API Old V1 端点枚举
656/// 对应 meta.project = ccm_doc, meta.version = old
657#[derive(Debug, Clone, PartialEq)]
658pub enum CcmDocApiOld {
659    /// 创建旧版文档
660    Create,
661    /// 获取旧版文档元信息
662    Meta(String), // doc_token
663    /// 获取旧版文档中的电子表格元数据
664    SheetMeta(String), // doc_token
665    /// 获取旧版文档纯文本内容
666    RawContent(String), // doc_token
667    /// 获取旧版文档富文本内容
668    Content(String), // doc_token
669    /// 编辑旧版文档内容
670    BatchUpdate(String), // doc_token
671}
672
673impl CcmDocApiOld {
674    /// 生成对应的 URL
675    pub fn to_url(&self) -> String {
676        match self {
677            CcmDocApiOld::Create => "/open-apis/doc/v2/create".to_string(),
678            CcmDocApiOld::Meta(doc_token) => {
679                format!("/open-apis/doc/v2/meta/{doc_token}")
680            }
681            CcmDocApiOld::SheetMeta(doc_token) => {
682                format!("/open-apis/doc/v2/{doc_token}/sheet_meta")
683            }
684            CcmDocApiOld::RawContent(doc_token) => {
685                format!("/open-apis/doc/v2/{doc_token}/raw_content")
686            }
687            CcmDocApiOld::Content(doc_token) => {
688                format!("/open-apis/doc/v2/{doc_token}/content")
689            }
690            CcmDocApiOld::BatchUpdate(doc_token) => {
691                format!("/open-apis/doc/v2/{doc_token}/batch_update")
692            }
693        }
694    }
695}
696
697/// CCM Docs API Old V1 端点枚举
698/// 对应 meta.project = ccm_docs, meta.version = old
699#[derive(Debug, Clone, PartialEq)]
700pub enum CcmDocsApiOld {
701    /// 搜索云文档
702    SearchObject,
703    /// 获取元数据
704    Meta,
705}
706
707impl CcmDocsApiOld {
708    /// 生成对应的 URL
709    pub fn to_url(&self) -> String {
710        match self {
711            CcmDocsApiOld::SearchObject => "/open-apis/suite/docs-api/search/object".to_string(),
712            CcmDocsApiOld::Meta => "/open-apis/suite/docs-api/meta".to_string(),
713        }
714    }
715}
716
717/// CCM Drive Explorer API Old V2 端点枚举
718/// 对应 meta.project = ccm_drive_explorer, meta.version = old
719#[derive(Debug, Clone, PartialEq)]
720pub enum CcmDriveExplorerApiOld {
721    /// 获取我的空间(根文件夹)元数据
722    RootFolderMeta,
723    /// 获取文件夹元数据
724    FolderMeta(String), // folder_token
725    /// 新建文件
726    File(String), // folder_token
727    /// 删除Sheet
728    FileSpreadsheets(String), // spreadsheet_token
729    /// 复制文档
730    FileCopy(String), // file_token
731    /// 删除Doc
732    FileDocs(String), // doc_token
733    /// 获取文件夹下的文档清单
734    FolderChildren(String), // folder_token
735    /// 新建文件夹
736    Folder(String), // folder_token
737}
738
739impl CcmDriveExplorerApiOld {
740    /// 生成对应的 URL
741    pub fn to_url(&self) -> String {
742        match self {
743            CcmDriveExplorerApiOld::RootFolderMeta => {
744                "/open-apis/drive/explorer/v2/root_folder/meta".to_string()
745            }
746            CcmDriveExplorerApiOld::FolderMeta(folder_token) => {
747                format!("/open-apis/drive/explorer/v2/folder/{folder_token}/meta")
748            }
749            CcmDriveExplorerApiOld::File(folder_token) => {
750                format!("/open-apis/drive/explorer/v2/file/{folder_token}")
751            }
752            CcmDriveExplorerApiOld::FileSpreadsheets(spreadsheet_token) => {
753                format!("/open-apis/drive/explorer/v2/file/spreadsheets/{spreadsheet_token}")
754            }
755            CcmDriveExplorerApiOld::FileCopy(file_token) => {
756                format!("/open-apis/drive/explorer/v2/file/copy/files/{file_token}")
757            }
758            CcmDriveExplorerApiOld::FileDocs(doc_token) => {
759                format!("/open-apis/drive/explorer/v2/file/docs/{doc_token}")
760            }
761            CcmDriveExplorerApiOld::FolderChildren(folder_token) => {
762                format!("/open-apis/drive/explorer/v2/folder/{folder_token}/children")
763            }
764            CcmDriveExplorerApiOld::Folder(folder_token) => {
765                format!("/open-apis/drive/explorer/v2/folder/{folder_token}")
766            }
767        }
768    }
769}
770
771/// CCM Drive Explorer API V1 端点枚举
772/// 对应 meta.project = ccm_drive_explorer, meta.version = v1
773#[derive(Debug, Clone, PartialEq)]
774pub enum CcmDriveExplorerApi {
775    /// 获取根目录元数据
776    RootFolderMeta,
777    /// 获取文件夹元数据
778    FolderMeta(String), // folder_token
779    /// 获取文件元数据
780    File(String), // file_token
781    /// 复制文件
782    FileCopy(String), // file_token
783    /// 获取文档文件信息
784    FileDocs(String), // file_token
785    /// 获取表格文件信息
786    FileSpreadsheets(String), // file_token
787    /// 获取文件夹子内容
788    FolderChildren(String), // folder_token
789    /// 创建文件夹
790    Folder,
791}
792
793impl CcmDriveExplorerApi {
794    /// 生成对应的 URL
795    pub fn to_url(&self) -> String {
796        match self {
797            CcmDriveExplorerApi::RootFolderMeta => {
798                "/open-apis/drive/v1/explorer/root_folder/meta".to_string()
799            }
800            CcmDriveExplorerApi::FolderMeta(folder_token) => {
801                format!("/open-apis/drive/v1/explorer/folder/{folder_token}/meta")
802            }
803            CcmDriveExplorerApi::File(file_token) => {
804                format!("/open-apis/drive/v1/explorer/file/{file_token}")
805            }
806            CcmDriveExplorerApi::FileCopy(file_token) => {
807                format!("/open-apis/drive/v1/explorer/file/copy/files/{file_token}")
808            }
809            CcmDriveExplorerApi::FileDocs(file_token) => {
810                format!("/open-apis/drive/v1/explorer/file/docs/{file_token}")
811            }
812            CcmDriveExplorerApi::FileSpreadsheets(file_token) => {
813                format!("/open-apis/drive/v1/explorer/file/spreadsheets/{file_token}")
814            }
815            CcmDriveExplorerApi::FolderChildren(folder_token) => {
816                format!("/open-apis/drive/v1/explorer/folder/{folder_token}/children")
817            }
818            CcmDriveExplorerApi::Folder => "/open-apis/drive/v1/explorer/folder".to_string(),
819        }
820    }
821
822    /// 生成带参数的 URL
823    pub fn to_url_with_params(&self, params: &[(&str, String)]) -> String {
824        let base_url = self.to_url();
825        if params.is_empty() {
826            return base_url;
827        }
828
829        let query_string = params
830            .iter()
831            .map(|(key, value)| format!("{}={}", key, simple_url_encode(value)))
832            .collect::<Vec<_>>()
833            .join("&");
834
835        format!("{base_url}?{query_string}")
836    }
837}
838
839/// 简单的URL编码函数,用于查询参数编码
840fn simple_url_encode(input: &str) -> String {
841    input
842        .chars()
843        .map(|c| match c {
844            'A'..='Z' | 'a'..='z' | '0'..='9' | '-' | '_' | '.' | '~' => c.to_string(),
845            _ => format!("%{:02X}", c as u8),
846        })
847        .collect()
848}
849
850/// CCM Drive Permission API V1 端点枚举
851/// 对应 meta.project = permission, meta.version = v1
852#[derive(Debug, Clone, PartialEq)]
853pub enum PermissionApi {
854    /// 判断协作者是否有某权限
855    MemberPermitted,
856    /// 转移拥有者
857    MemberTransfer,
858    /// 获取云文档权限设置V2
859    Public,
860}
861
862impl PermissionApi {
863    /// 生成对应的 URL
864    pub fn to_url(&self) -> String {
865        match self {
866            PermissionApi::MemberPermitted => {
867                "/open-apis/drive/v1/permission/member/permitted".to_string()
868            }
869            PermissionApi::MemberTransfer => {
870                "/open-apis/drive/v1/permission/member/transfer".to_string()
871            }
872            PermissionApi::Public => "/open-apis/drive/v1/permission/v2/public/".to_string(),
873        }
874    }
875}
876
877/// CCM Drive Permission API Old V2 端点枚举
878/// 对应 meta.project = permission, meta.version = old
879#[derive(Debug, Clone, PartialEq)]
880pub enum PermissionApiOld {
881    /// 判断协作者是否有某权限
882    MemberPermitted,
883    /// 转移拥有者
884    MemberTransfer,
885    /// 获取云文档权限设置V2
886    Public,
887}
888
889impl PermissionApiOld {
890    /// 生成对应的 URL
891    pub fn to_url(&self) -> String {
892        match self {
893            PermissionApiOld::MemberPermitted => {
894                "/open-apis/drive/v1/permission/member/permitted".to_string()
895            }
896            PermissionApiOld::MemberTransfer => {
897                "/open-apis/drive/v1/permission/member/transfer".to_string()
898            }
899            PermissionApiOld::Public => "/open-apis/drive/v1/permission/v2/public/".to_string(),
900        }
901    }
902}
903
904/// CCM Sheet API Old V2 端点枚举
905/// 对应 meta.project = ccm_sheet, meta.version = old
906#[derive(Debug, Clone, PartialEq)]
907pub enum CcmSheetApiOld {
908    /// 操作工作表 (第一个)
909    OperateSheets(String), // spreadsheet_token
910    /// 更新工作表属性 (第二个)
911    UpdateSheetProperties(String), // spreadsheet_token
912    /// 增加行列
913    DimensionRange(String), // spreadsheet_token
914    /// 插入行列
915    InsertDimensionRange(String), // spreadsheet_token
916    /// 更新行列
917    DimensionRangeUpdate(String), // spreadsheet_token
918    /// 删除行列
919    DimensionRangeDelete(String), // spreadsheet_token
920    /// 合并单元格
921    MergeCells(String), // spreadsheet_token
922    /// 拆分单元格
923    UnmergeCells(String), // spreadsheet_token
924    /// 设置单元格样式
925    Style(String), // spreadsheet_token
926    /// 批量设置单元格样式
927    StylesBatchUpdate(String), // spreadsheet_token
928    /// 插入数据
929    ValuesPrepend(String), // spreadsheet_token
930    /// 追加数据
931    ValuesAppend(String), // spreadsheet_token
932    /// 写入图片
933    ValuesImage(String), // spreadsheet_token
934    /// 读取单个范围
935    ValuesRange(String, String), // spreadsheet_token, range
936    /// 读取多个范围
937    ValuesBatchGet(String), // spreadsheet_token
938    /// 向单个范围写入数据
939    Values(String), // spreadsheet_token
940    /// 向多个范围写入数据
941    ValuesBatchUpdate(String), // spreadsheet_token
942    /// 增加保护范围
943    ProtectedDimension(String), // spreadsheet_token
944    /// 修改保护范围
945    ProtectedRangeBatchUpdate(String), // spreadsheet_token
946    /// 获取保护范围
947    ProtectedRangeBatchGet(String), // spreadsheet_token
948    /// 删除保护范围
949    ProtectedRangeBatchDel(String), // spreadsheet_token
950    /// 获取表格元数据
951    Metainfo(String), // spreadsheet_token
952    /// 更新表格属性
953    Properties(String), // spreadsheet_token
954    /// 导入表格
955    Import,
956    /// 查询导入结果
957    ImportResult,
958    /// 获取条件格式
959    ConditionFormats(String), // spreadsheet_token
960    /// 批量创建条件格式
961    ConditionFormatsBatchCreate(String), // spreadsheet_token
962    /// 批量删除条件格式
963    ConditionFormatsBatchDelete(String), // spreadsheet_token
964    /// 批量更新条件格式
965    ConditionFormatsBatchUpdate(String), // spreadsheet_token
966    /// 获取数据验证规则
967    DataValidation(String), // spreadsheet_token
968    /// 创建数据验证规则
969    DataValidationCreate(String), // spreadsheet_token
970    /// 更新下拉列表设置(PUT)
971    DataValidationUpdate(String, String), // spreadsheet_token, sheet_id
972    /// 删除下拉列表设置(DELETE,按 range 删除)
973    DataValidationDelete(String), // spreadsheet_token
974    /// 读取单个范围
975    ReadSingleRange(String, String), // spreadsheet_token, range
976    /// 读取多个范围
977    ReadMultipleRanges(String), // spreadsheet_token
978    /// 写入单个范围
979    WriteSingleRange(String), // spreadsheet_token
980    /// 批量写入范围
981    BatchWriteRanges(String), // spreadsheet_token
982    /// 追加数据
983    AppendValues(String), // spreadsheet_token
984    /// 插入数据
985    InsertValues(String), // spreadsheet_token
986    /// 获取电子表格信息
987    GetSpreadsheet(String), // spreadsheet_token
988    /// 创建电子表格
989    CreateSpreadsheet,
990    /// 修改电子表格属性
991    UpdateSpreadsheet(String), // spreadsheet_token
992    /// 操作工作表
993    AddSheet(String), // spreadsheet_token
994    /// 查询工作表
995    GetSheet(String, String), // spreadsheet_token, sheet_id
996    /// 更新工作表
997    UpdateSheet(String), // spreadsheet_token
998    /// 删除工作表
999    DeleteSheet(String), // spreadsheet_token
1000    /// 创建筛选 (V3)
1001    CreateFilter(String), // spreadsheet_token
1002    /// 获取筛选 (V3)
1003    GetFilter(String), // spreadsheet_token
1004    /// 更新筛选 (V3)
1005    UpdateFilter(String), // spreadsheet_token
1006    /// 删除筛选 (V3)
1007    DeleteFilter(String), // spreadsheet_token
1008    /// 创建筛选视图 (V3)
1009    CreateFilterView(String, String), // spreadsheet_token, sheet_id
1010    /// 更新筛选视图 (V3)
1011    UpdateFilterView(String, String, String), // spreadsheet_token, sheet_id, filter_view_id
1012    /// 查询筛选视图 (V3)
1013    QueryFilterViews(String, String), // spreadsheet_token, sheet_id
1014    /// 获取筛选视图 (V3)
1015    GetFilterView(String, String, String), // spreadsheet_token, sheet_id, filter_view_id
1016    /// 删除筛选视图 (V3)
1017    DeleteFilterView(String, String, String), // spreadsheet_token, sheet_id, filter_view_id
1018    /// 创建筛选条件 (V3)
1019    CreateFilterCondition(String, String, String), // spreadsheet_token, sheet_id, filter_view_id
1020    /// 更新筛选条件 (V3)
1021    UpdateFilterCondition(String, String, String, String), // spreadsheet_token, sheet_id, filter_view_id, condition_id
1022    /// 查询筛选条件 (V3)
1023    QueryFilterConditions(String, String, String), // spreadsheet_token, sheet_id, filter_view_id
1024    /// 获取筛选条件 (V3)
1025    GetFilterCondition(String, String, String, String), // spreadsheet_token, sheet_id, filter_view_id, condition_id
1026    /// 删除筛选条件 (V3)
1027    DeleteFilterCondition(String, String, String, String), // spreadsheet_token, sheet_id, filter_view_id, condition_id
1028    /// 创建浮动图片 (V3)
1029    CreateFloatImage(String, String), // spreadsheet_token, sheet_id
1030    /// 更新浮动图片 (V3)
1031    UpdateFloatImage(String, String, String), // spreadsheet_token, sheet_id, float_image_id
1032    /// 获取浮动图片 (V3)
1033    GetFloatImage(String, String, String), // spreadsheet_token, sheet_id, float_image_id
1034    /// 查询浮动图片 (V3)
1035    QueryFloatImages(String, String), // spreadsheet_token, sheet_id
1036    /// 删除浮动图片 (V3)
1037    DeleteFloatImage(String, String, String), // spreadsheet_token, sheet_id, float_image_id
1038    /// 删除范围 (V3)
1039    DeleteRange(String), // spreadsheet_token
1040    /// 插入维度 (V3)
1041    InsertDimension(String), // spreadsheet_token
1042    /// 移动维度 (V3)
1043    MoveDimension(String), // spreadsheet_token
1044    /// 替换范围 (V3)
1045    ReplaceRange(String), // spreadsheet_token
1046    /// 查找替换 (V3)
1047    FindReplace(String), // spreadsheet_token
1048}
1049
1050impl CcmSheetApiOld {
1051    /// 生成对应的 URL
1052    pub fn to_url(&self) -> String {
1053        match self {
1054            CcmSheetApiOld::OperateSheets(spreadsheet_token) => {
1055                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update")
1056            }
1057            CcmSheetApiOld::UpdateSheetProperties(spreadsheet_token) => {
1058                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update")
1059            }
1060            CcmSheetApiOld::Style(spreadsheet_token) => {
1061                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/style")
1062            }
1063            CcmSheetApiOld::StylesBatchUpdate(spreadsheet_token) => {
1064                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/styles_batch_update")
1065            }
1066            CcmSheetApiOld::ValuesPrepend(spreadsheet_token) => {
1067                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_prepend")
1068            }
1069            CcmSheetApiOld::ValuesAppend(spreadsheet_token) => {
1070                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_append")
1071            }
1072            CcmSheetApiOld::ValuesImage(spreadsheet_token) => {
1073                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_image")
1074            }
1075            CcmSheetApiOld::ValuesRange(spreadsheet_token, range) => {
1076                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values/{range}")
1077            }
1078            CcmSheetApiOld::ValuesBatchGet(spreadsheet_token) => {
1079                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_batch_get")
1080            }
1081            CcmSheetApiOld::Values(spreadsheet_token) => {
1082                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values")
1083            }
1084            CcmSheetApiOld::ValuesBatchUpdate(spreadsheet_token) => {
1085                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_batch_update")
1086            }
1087            CcmSheetApiOld::DimensionRange(spreadsheet_token) => {
1088                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dimension_range")
1089            }
1090            CcmSheetApiOld::InsertDimensionRange(spreadsheet_token) => {
1091                format!(
1092                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/insert_dimension_range"
1093                )
1094            }
1095            CcmSheetApiOld::DimensionRangeUpdate(spreadsheet_token) => {
1096                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dimension_range")
1097            }
1098            CcmSheetApiOld::DimensionRangeDelete(spreadsheet_token) => {
1099                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dimension_range")
1100            }
1101            CcmSheetApiOld::MergeCells(spreadsheet_token) => {
1102                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/merge_cells")
1103            }
1104            CcmSheetApiOld::UnmergeCells(spreadsheet_token) => {
1105                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/unmerge_cells")
1106            }
1107            CcmSheetApiOld::ProtectedDimension(spreadsheet_token) => {
1108                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/protected_dimension")
1109            }
1110            CcmSheetApiOld::ProtectedRangeBatchUpdate(spreadsheet_token) => {
1111                format!(
1112                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/protected_range_batch_update"
1113                )
1114            }
1115            CcmSheetApiOld::ProtectedRangeBatchGet(spreadsheet_token) => {
1116                format!(
1117                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/protected_range_batch_get"
1118                )
1119            }
1120            CcmSheetApiOld::ProtectedRangeBatchDel(spreadsheet_token) => {
1121                format!(
1122                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/protected_range_batch_del"
1123                )
1124            }
1125            CcmSheetApiOld::Metainfo(spreadsheet_token) => {
1126                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/metainfo")
1127            }
1128            CcmSheetApiOld::Properties(spreadsheet_token) => {
1129                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/properties")
1130            }
1131            CcmSheetApiOld::Import => "/open-apis/sheets/v2/import".to_string(),
1132            CcmSheetApiOld::ImportResult => "/open-apis/sheets/v2/import/result".to_string(),
1133            CcmSheetApiOld::ConditionFormats(spreadsheet_token) => {
1134                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/condition_formats")
1135            }
1136            CcmSheetApiOld::ConditionFormatsBatchCreate(spreadsheet_token) => {
1137                format!(
1138                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/condition_formats/batch_create"
1139                )
1140            }
1141            CcmSheetApiOld::ConditionFormatsBatchDelete(spreadsheet_token) => {
1142                format!(
1143                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/condition_formats/batch_delete"
1144                )
1145            }
1146            CcmSheetApiOld::ConditionFormatsBatchUpdate(spreadsheet_token) => {
1147                format!(
1148                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/condition_formats/batch_update"
1149                )
1150            }
1151            CcmSheetApiOld::DataValidation(spreadsheet_token) => {
1152                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dataValidation")
1153            }
1154            CcmSheetApiOld::DataValidationCreate(spreadsheet_token) => {
1155                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dataValidation")
1156            }
1157            CcmSheetApiOld::DataValidationUpdate(spreadsheet_token, sheet_id) => {
1158                format!(
1159                    "/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dataValidation/{sheet_id}"
1160                )
1161            }
1162            CcmSheetApiOld::DataValidationDelete(spreadsheet_token) => {
1163                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/dataValidation")
1164            }
1165            CcmSheetApiOld::ReadSingleRange(spreadsheet_token, range) => {
1166                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values/{range}")
1167            }
1168            CcmSheetApiOld::ReadMultipleRanges(spreadsheet_token) => {
1169                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_batch_get")
1170            }
1171            CcmSheetApiOld::WriteSingleRange(spreadsheet_token) => {
1172                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values")
1173            }
1174            CcmSheetApiOld::BatchWriteRanges(spreadsheet_token) => {
1175                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_batch_update")
1176            }
1177            CcmSheetApiOld::AppendValues(spreadsheet_token) => {
1178                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_append")
1179            }
1180            CcmSheetApiOld::InsertValues(spreadsheet_token) => {
1181                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_prepend")
1182            }
1183            CcmSheetApiOld::GetSpreadsheet(spreadsheet_token) => {
1184                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}")
1185            }
1186            CcmSheetApiOld::CreateSpreadsheet => "/open-apis/sheets/v3/spreadsheets".to_string(),
1187            CcmSheetApiOld::UpdateSpreadsheet(spreadsheet_token) => {
1188                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}")
1189            }
1190            CcmSheetApiOld::AddSheet(spreadsheet_token) => {
1191                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update")
1192            }
1193            CcmSheetApiOld::GetSheet(spreadsheet_token, sheet_id) => {
1194                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}")
1195            }
1196            CcmSheetApiOld::UpdateSheet(spreadsheet_token) => {
1197                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update")
1198            }
1199            CcmSheetApiOld::DeleteSheet(spreadsheet_token) => {
1200                format!("/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update")
1201            }
1202            CcmSheetApiOld::CreateFilter(spreadsheet_token) => {
1203                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/filterViews")
1204            }
1205            CcmSheetApiOld::GetFilter(spreadsheet_token) => {
1206                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/filterViews/query")
1207            }
1208            CcmSheetApiOld::UpdateFilter(spreadsheet_token) => {
1209                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/filterViews")
1210            }
1211            CcmSheetApiOld::DeleteFilter(spreadsheet_token) => {
1212                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/filterViews")
1213            }
1214            CcmSheetApiOld::CreateFilterView(spreadsheet_token, sheet_id) => {
1215                format!(
1216                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views"
1217                )
1218            }
1219            CcmSheetApiOld::UpdateFilterView(spreadsheet_token, sheet_id, filter_view_id) => {
1220                format!(
1221                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}"
1222                )
1223            }
1224            CcmSheetApiOld::QueryFilterViews(spreadsheet_token, sheet_id) => {
1225                format!(
1226                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/query"
1227                )
1228            }
1229            CcmSheetApiOld::GetFilterView(spreadsheet_token, sheet_id, filter_view_id) => {
1230                format!(
1231                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}"
1232                )
1233            }
1234            CcmSheetApiOld::DeleteFilterView(spreadsheet_token, sheet_id, filter_view_id) => {
1235                format!(
1236                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}"
1237                )
1238            }
1239            CcmSheetApiOld::CreateFilterCondition(spreadsheet_token, sheet_id, filter_view_id) => {
1240                format!(
1241                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions"
1242                )
1243            }
1244            CcmSheetApiOld::UpdateFilterCondition(
1245                spreadsheet_token,
1246                sheet_id,
1247                filter_view_id,
1248                condition_id,
1249            ) => {
1250                format!(
1251                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions/{condition_id}"
1252                )
1253            }
1254            CcmSheetApiOld::QueryFilterConditions(spreadsheet_token, sheet_id, filter_view_id) => {
1255                format!(
1256                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions/query"
1257                )
1258            }
1259            CcmSheetApiOld::GetFilterCondition(
1260                spreadsheet_token,
1261                sheet_id,
1262                filter_view_id,
1263                condition_id,
1264            ) => {
1265                format!(
1266                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions/{condition_id}"
1267                )
1268            }
1269            CcmSheetApiOld::DeleteFilterCondition(
1270                spreadsheet_token,
1271                sheet_id,
1272                filter_view_id,
1273                condition_id,
1274            ) => {
1275                format!(
1276                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions/{condition_id}"
1277                )
1278            }
1279            CcmSheetApiOld::CreateFloatImage(spreadsheet_token, sheet_id) => {
1280                format!(
1281                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images"
1282                )
1283            }
1284            CcmSheetApiOld::UpdateFloatImage(spreadsheet_token, sheet_id, float_image_id) => {
1285                format!(
1286                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images/{float_image_id}"
1287                )
1288            }
1289            CcmSheetApiOld::GetFloatImage(spreadsheet_token, sheet_id, float_image_id) => {
1290                format!(
1291                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images/{float_image_id}"
1292                )
1293            }
1294            CcmSheetApiOld::QueryFloatImages(spreadsheet_token, sheet_id) => {
1295                format!(
1296                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images/query"
1297                )
1298            }
1299            CcmSheetApiOld::DeleteFloatImage(spreadsheet_token, sheet_id, float_image_id) => {
1300                format!(
1301                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images/{float_image_id}"
1302                )
1303            }
1304            CcmSheetApiOld::DeleteRange(spreadsheet_token) => {
1305                format!(
1306                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/dimensionRange/delete"
1307                )
1308            }
1309            CcmSheetApiOld::InsertDimension(spreadsheet_token) => {
1310                format!(
1311                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/dimensionRange/insert"
1312                )
1313            }
1314            CcmSheetApiOld::MoveDimension(spreadsheet_token) => {
1315                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/dimensionRange/move")
1316            }
1317            CcmSheetApiOld::ReplaceRange(spreadsheet_token) => {
1318                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/values/batchReplace")
1319            }
1320            CcmSheetApiOld::FindReplace(spreadsheet_token) => {
1321                format!(
1322                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/values/batchFindReplace"
1323                )
1324            }
1325        }
1326    }
1327}
1328
1329/// Drive API 端点枚举
1330#[derive(Debug, Clone, PartialEq)]
1331pub enum DriveApi {
1332    // V1 APIs - 文件操作
1333    /// 获取文件夹中的文件清单
1334    ListFiles,
1335    /// 新建文件夹
1336    CreateFolder,
1337    /// 查询异步任务状态
1338    TaskCheck,
1339    /// 获取文件元数据(批量查询)
1340    BatchQueryMetas,
1341    /// 获取文件统计信息
1342    GetFileStatistics(String), // file_token
1343    /// 获取文件访问记录
1344    ListFileViewRecords(String), // file_token
1345    /// 复制文件
1346    CopyFile(String), // file_token
1347    /// 移动文件或文件夹
1348    MoveFile(String), // file_token
1349    /// 删除文件或文件夹
1350    DeleteFile(String), // file_token
1351    /// 创建文件快捷方式
1352    CreateShortcut,
1353    /// 上传文件
1354    UploadFile,
1355    /// 分片上传文件-预上传
1356    UploadPrepare,
1357    /// 分片上传文件-上传分片
1358    UploadPart,
1359    /// 分片上传文件-完成上传
1360    UploadFinish,
1361    /// 下载文件
1362    DownloadFile(String), // file_token
1363    /// 创建导入任务
1364    CreateImportTask,
1365    /// 查询导入任务结果
1366    GetImportTask(String), // ticket
1367    /// 创建导出任务
1368    CreateExportTask,
1369    /// 查询导出任务结果
1370    GetExportTask(String), // ticket
1371    /// 下载导出文件
1372    DownloadExportFile(String), // file_token
1373    /// 上传素材
1374    UploadMedia,
1375    /// 分片上传素材-预上传
1376    UploadMediaPrepare,
1377    /// 分片上传素材-上传分片
1378    UploadMediaPart,
1379    /// 分片上传素材-完成上传
1380    UploadMediaFinish,
1381    /// 下载素材
1382    DownloadMedia(String), // file_token
1383    /// 获取素材临时下载链接
1384    GetMediaTempDownloadUrls,
1385    /// 创建文档版本
1386    CreateFileVersion(String), // file_token
1387    /// 获取文档版本列表
1388    ListFileVersions(String), // file_token
1389    /// 获取文档版本信息
1390    GetFileVersion(String, String), // file_token, version_id
1391    /// 删除文档版本
1392    DeleteFileVersion(String, String), // file_token, version_id
1393    /// 订阅云文档事件
1394    SubscribeFile(String), // file_token
1395    /// 查询云文档事件订阅状态
1396    GetFileSubscribe(String), // file_token
1397    /// 取消云文档事件订阅
1398    DeleteFileSubscribe(String), // file_token
1399    /// 增加协作者权限
1400    CreatePermissionMember(String), // token
1401    /// 批量增加协作者权限
1402    BatchCreatePermissionMember(String), // token
1403    /// 更新协作者权限
1404    UpdatePermissionMember(String, String), // token, member_id
1405    /// 获取云文档协作者
1406    ListPermissionMembers(String), // token
1407    /// 移除云文档协作者权限
1408    DeletePermissionMember(String, String), // token, member_id
1409    /// 转移云文档所有者
1410    TransferOwner(String), // token
1411    /// 判断用户云文档权限
1412    AuthPermissionMember(String), // token
1413    /// 更新云文档权限设置
1414    UpdatePublicPermission(String), // token
1415    /// 获取云文档权限设置
1416    GetPublicPermission(String), // token
1417    /// 启用云文档密码
1418    CreatePublicPassword(String), // token
1419    /// 刷新云文档密码
1420    UpdatePublicPassword(String), // token
1421    /// 停用云文档密码
1422    DeletePublicPassword(String), // token
1423    /// 获取云文档所有评论
1424    ListFileComments(String), // file_token
1425    /// 批量获取评论
1426    BatchQueryComments(String), // file_token
1427    /// 解决/恢复评论
1428    PatchComment(String, String), // file_token, comment_id
1429    /// 添加全文评论
1430    CreateComment(String), // file_token
1431    /// 获取全文评论
1432    GetComment(String, String), // file_token, comment_id
1433    /// 获取回复信息
1434    ListCommentReplies(String, String), // file_token, comment_id
1435    /// 更新回复的内容
1436    UpdateCommentReply(String, String, String), // file_token, comment_id, reply_id
1437    /// 删除回复
1438    DeleteCommentReply(String, String, String), // file_token, comment_id, reply_id
1439    /// 获取订阅状态
1440    GetFileSubscription(String, String), // file_token, subscription_id
1441    /// 创建订阅
1442    CreateFileSubscription(String), // file_token
1443    /// 更新订阅状态
1444    UpdateFileSubscription(String, String), // file_token, subscription_id
1445
1446    // V2 APIs
1447    /// 获取云文档的点赞者列表
1448    ListFileLikes(String), // file_token
1449    /// 获取云文档权限设置(v2)
1450    GetPublicPermissionV2(String), // token
1451    /// 更新云文档权限设置(v2)
1452    UpdatePublicPermissionV2(String), // token
1453
1454    // Media Upload Task APIs
1455    /// 创建媒体上传任务
1456    MediaUploadTasks,
1457    /// 获取媒体上传任务
1458    MediaUploadTask(String), // task_id
1459    /// 创建媒体分享链接
1460    CreateMediaShareLink(String), // file_token
1461    /// 获取公开密码
1462    GetPublicPassword(String), // file_token
1463}
1464
1465impl DriveApi {
1466    /// 生成对应的 URL
1467    pub fn to_url(&self) -> String {
1468        match self {
1469            // V1 File APIs
1470            DriveApi::ListFiles => "/open-apis/drive/v1/files".to_string(),
1471            DriveApi::CreateFolder => "/open-apis/drive/v1/files/create_folder".to_string(),
1472            DriveApi::TaskCheck => "/open-apis/drive/v1/files/task_check".to_string(),
1473            DriveApi::BatchQueryMetas => "/open-apis/drive/v1/metas/batch_query".to_string(),
1474            DriveApi::GetFileStatistics(file_token) => {
1475                format!("/open-apis/drive/v1/files/{file_token}/statistics")
1476            }
1477            DriveApi::ListFileViewRecords(file_token) => {
1478                format!("/open-apis/drive/v1/files/{file_token}/view_records")
1479            }
1480            DriveApi::CopyFile(file_token) => {
1481                format!("/open-apis/drive/v1/files/{file_token}/copy")
1482            }
1483            DriveApi::MoveFile(file_token) => {
1484                format!("/open-apis/drive/v1/files/{file_token}/move")
1485            }
1486            DriveApi::DeleteFile(file_token) => {
1487                format!("/open-apis/drive/v1/files/{file_token}")
1488            }
1489            DriveApi::CreateShortcut => "/open-apis/drive/v1/files/create_shortcut".to_string(),
1490            DriveApi::UploadFile => "/open-apis/drive/v1/files/upload_all".to_string(),
1491            DriveApi::UploadPrepare => "/open-apis/drive/v1/files/upload_prepare".to_string(),
1492            DriveApi::UploadPart => "/open-apis/drive/v1/files/upload_part".to_string(),
1493            DriveApi::UploadFinish => "/open-apis/drive/v1/files/upload_finish".to_string(),
1494            DriveApi::DownloadFile(file_token) => {
1495                format!("/open-apis/drive/v1/files/{file_token}/download")
1496            }
1497
1498            // Import/Export Task APIs
1499            DriveApi::CreateImportTask => "/open-apis/drive/v1/import_tasks".to_string(),
1500            DriveApi::GetImportTask(ticket) => {
1501                format!("/open-apis/drive/v1/import_tasks/{ticket}")
1502            }
1503            DriveApi::CreateExportTask => "/open-apis/drive/v1/export_tasks".to_string(),
1504            DriveApi::GetExportTask(ticket) => {
1505                format!("/open-apis/drive/v1/export_tasks/{ticket}")
1506            }
1507            DriveApi::DownloadExportFile(file_token) => {
1508                format!("/open-apis/drive/v1/export_tasks/file/{file_token}/download")
1509            }
1510
1511            // Media APIs
1512            DriveApi::UploadMedia => "/open-apis/drive/v1/medias/upload_all".to_string(),
1513            DriveApi::UploadMediaPrepare => "/open-apis/drive/v1/medias/upload_prepare".to_string(),
1514            DriveApi::UploadMediaPart => "/open-apis/drive/v1/medias/upload_part".to_string(),
1515            DriveApi::UploadMediaFinish => "/open-apis/drive/v1/medias/upload_finish".to_string(),
1516            DriveApi::DownloadMedia(file_token) => {
1517                format!("/open-apis/drive/v1/medias/{file_token}/download")
1518            }
1519            DriveApi::GetMediaTempDownloadUrls => {
1520                "/open-apis/drive/v1/medias/batch_get_tmp_download_url".to_string()
1521            }
1522
1523            // File Version APIs
1524            DriveApi::CreateFileVersion(file_token) => {
1525                format!("/open-apis/drive/v1/files/{file_token}/versions")
1526            }
1527            DriveApi::ListFileVersions(file_token) => {
1528                format!("/open-apis/drive/v1/files/{file_token}/versions")
1529            }
1530            DriveApi::GetFileVersion(file_token, version_id) => {
1531                format!("/open-apis/drive/v1/files/{file_token}/versions/{version_id}")
1532            }
1533            DriveApi::DeleteFileVersion(file_token, version_id) => {
1534                format!("/open-apis/drive/v1/files/{file_token}/versions/{version_id}")
1535            }
1536
1537            // Subscription APIs
1538            DriveApi::SubscribeFile(file_token) => {
1539                format!("/open-apis/drive/v1/files/{file_token}/subscribe")
1540            }
1541            DriveApi::GetFileSubscribe(file_token) => {
1542                format!("/open-apis/drive/v1/files/{file_token}/get_subscribe")
1543            }
1544            DriveApi::DeleteFileSubscribe(file_token) => {
1545                format!("/open-apis/drive/v1/files/{file_token}/delete_subscribe")
1546            }
1547
1548            // Permission Member APIs
1549            DriveApi::CreatePermissionMember(token) => {
1550                format!("/open-apis/drive/v1/permissions/{token}/members")
1551            }
1552            DriveApi::BatchCreatePermissionMember(token) => {
1553                format!("/open-apis/drive/v1/permissions/{token}/members/batch_create")
1554            }
1555            DriveApi::UpdatePermissionMember(token, member_id) => {
1556                format!("/open-apis/drive/v1/permissions/{token}/members/{member_id}")
1557            }
1558            DriveApi::ListPermissionMembers(token) => {
1559                format!("/open-apis/drive/v1/permissions/{token}/members")
1560            }
1561            DriveApi::DeletePermissionMember(token, member_id) => {
1562                format!("/open-apis/drive/v1/permissions/{token}/members/{member_id}")
1563            }
1564            DriveApi::TransferOwner(token) => {
1565                format!("/open-apis/drive/v1/permissions/{token}/members/transfer_owner")
1566            }
1567            DriveApi::AuthPermissionMember(token) => {
1568                format!("/open-apis/drive/v1/permissions/{token}/members/auth")
1569            }
1570
1571            // Permission Public APIs
1572            DriveApi::UpdatePublicPermission(token) => {
1573                format!("/open-apis/drive/v1/permissions/{token}/public")
1574            }
1575            DriveApi::GetPublicPermission(token) => {
1576                format!("/open-apis/drive/v1/permissions/{token}/public")
1577            }
1578            DriveApi::CreatePublicPassword(token) => {
1579                format!("/open-apis/drive/v1/permissions/{token}/public/password")
1580            }
1581            DriveApi::UpdatePublicPassword(token) => {
1582                format!("/open-apis/drive/v1/permissions/{token}/public/password")
1583            }
1584            DriveApi::DeletePublicPassword(token) => {
1585                format!("/open-apis/drive/v1/permissions/{token}/public/password")
1586            }
1587
1588            // Comment APIs
1589            DriveApi::ListFileComments(file_token) => {
1590                format!("/open-apis/drive/v1/files/{file_token}/comments")
1591            }
1592            DriveApi::BatchQueryComments(file_token) => {
1593                format!("/open-apis/drive/v1/files/{file_token}/comments/batch_query")
1594            }
1595            DriveApi::PatchComment(file_token, comment_id) => {
1596                format!("/open-apis/drive/v1/files/{file_token}/comments/{comment_id}")
1597            }
1598            DriveApi::CreateComment(file_token) => {
1599                format!("/open-apis/drive/v1/files/{file_token}/comments")
1600            }
1601            DriveApi::GetComment(file_token, comment_id) => {
1602                format!("/open-apis/drive/v1/files/{file_token}/comments/{comment_id}")
1603            }
1604            DriveApi::ListCommentReplies(file_token, comment_id) => {
1605                format!("/open-apis/drive/v1/files/{file_token}/comments/{comment_id}/replies")
1606            }
1607            DriveApi::UpdateCommentReply(file_token, comment_id, reply_id) => {
1608                format!(
1609                    "/open-apis/drive/v1/files/{file_token}/comments/{comment_id}/replies/{reply_id}"
1610                )
1611            }
1612            DriveApi::DeleteCommentReply(file_token, comment_id, reply_id) => {
1613                format!(
1614                    "/open-apis/drive/v1/files/{file_token}/comments/{comment_id}/replies/{reply_id}"
1615                )
1616            }
1617
1618            // File Subscription APIs
1619            DriveApi::GetFileSubscription(file_token, subscription_id) => {
1620                format!("/open-apis/drive/v1/files/{file_token}/subscriptions/{subscription_id}")
1621            }
1622            DriveApi::CreateFileSubscription(file_token) => {
1623                format!("/open-apis/drive/v1/files/{file_token}/subscriptions")
1624            }
1625            DriveApi::UpdateFileSubscription(file_token, subscription_id) => {
1626                format!("/open-apis/drive/v1/files/{file_token}/subscriptions/{subscription_id}")
1627            }
1628
1629            // V2 APIs
1630            DriveApi::ListFileLikes(file_token) => {
1631                format!("/open-apis/drive/v2/files/{file_token}/likes")
1632            }
1633            DriveApi::GetPublicPermissionV2(token) => {
1634                format!("/open-apis/drive/v2/permissions/{token}/public")
1635            }
1636            DriveApi::UpdatePublicPermissionV2(token) => {
1637                format!("/open-apis/drive/v2/permissions/{token}/public")
1638            }
1639
1640            // Media Upload Task APIs
1641            DriveApi::MediaUploadTasks => "/open-apis/drive/v1/medias/upload_tasks".to_string(),
1642            DriveApi::MediaUploadTask(task_id) => {
1643                format!("/open-apis/drive/v1/medias/upload_tasks/{task_id}")
1644            }
1645            DriveApi::CreateMediaShareLink(file_token) => {
1646                format!("/open-apis/drive/v1/medias/{file_token}/share_link")
1647            }
1648            DriveApi::GetPublicPassword(file_token) => {
1649                format!("/open-apis/drive/v1/publics/{file_token}/password")
1650            }
1651        }
1652    }
1653}
1654
1655/// Wiki API 端点枚举
1656#[derive(Debug, Clone, PartialEq)]
1657pub enum WikiApi {
1658    // Space APIs
1659    /// 获取知识空间列表
1660    ListSpaces,
1661    /// 获取知识空间信息
1662    GetSpace,
1663    /// 创建知识空间
1664    CreateSpace,
1665
1666    // Space Member APIs
1667    /// 获取知识空间成员列表
1668    ListSpaceMembers(String), // space_id
1669    /// 添加知识空间成员
1670    CreateSpaceMember(String), // space_id
1671    /// 删除知识空间成员
1672    DeleteSpaceMember(String, String), // space_id, member_id
1673
1674    // Space Setting APIs
1675    /// 更新知识空间设置
1676    UpdateSpaceSetting(String), // space_id
1677
1678    // Space Node APIs
1679    /// 创建知识空间节点
1680    CreateSpaceNode(String), // space_id
1681    /// 获取知识空间节点信息
1682    GetSpaceNode,
1683    /// 获取知识空间子节点列表
1684    ListSpaceNodes,
1685    /// 移动知识空间节点
1686    MoveSpaceNode(String, String), // space_id, node_token
1687    /// 更新知识空间节点标题
1688    UpdateSpaceNodeTitle(String, String), // space_id, node_token
1689    /// 创建知识空间节点副本
1690    CopySpaceNode(String, String), // space_id, node_token
1691    /// 移动云空间文档至知识空间
1692    MoveDocsToWiki(String), // space_id
1693
1694    // Task APIs
1695    /// 获取任务结果
1696    GetTask(String), // task_id
1697
1698    // Node Search API (V1)
1699    /// 搜索Wiki节点
1700    SearchNodes,
1701}
1702
1703impl WikiApi {
1704    /// 生成对应的 URL
1705    pub fn to_url(&self) -> String {
1706        match self {
1707            // Space APIs
1708            WikiApi::ListSpaces => "/open-apis/wiki/v2/spaces".to_string(),
1709            WikiApi::GetSpace => "/open-apis/wiki/v2/spaces/get_node".to_string(),
1710            WikiApi::CreateSpace => "/open-apis/wiki/v2/spaces".to_string(),
1711
1712            // Space Member APIs
1713            WikiApi::ListSpaceMembers(space_id) => {
1714                format!("/open-apis/wiki/v2/spaces/{space_id}/members")
1715            }
1716            WikiApi::CreateSpaceMember(space_id) => {
1717                format!("/open-apis/wiki/v2/spaces/{space_id}/members")
1718            }
1719            WikiApi::DeleteSpaceMember(space_id, member_id) => {
1720                format!("/open-apis/wiki/v2/spaces/{space_id}/members/{member_id}")
1721            }
1722
1723            // Space Setting APIs
1724            WikiApi::UpdateSpaceSetting(space_id) => {
1725                format!("/open-apis/wiki/v2/spaces/{space_id}/setting")
1726            }
1727
1728            // Space Node APIs
1729            WikiApi::CreateSpaceNode(space_id) => {
1730                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes")
1731            }
1732            WikiApi::GetSpaceNode => "/open-apis/wiki/v2/spaces/get_node".to_string(),
1733            WikiApi::ListSpaceNodes => "/open-apis/wiki/v2/space.node/list".to_string(),
1734            WikiApi::MoveSpaceNode(space_id, node_token) => {
1735                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/{node_token}/move")
1736            }
1737            WikiApi::UpdateSpaceNodeTitle(space_id, node_token) => {
1738                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/{node_token}/update_title")
1739            }
1740            WikiApi::CopySpaceNode(space_id, node_token) => {
1741                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/{node_token}/copy")
1742            }
1743            WikiApi::MoveDocsToWiki(space_id) => {
1744                format!("/open-apis/wiki/v2/spaces/{space_id}/nodes/move_docs_to_wiki")
1745            }
1746
1747            // Task APIs
1748            WikiApi::GetTask(task_id) => {
1749                format!("/open-apis/wiki/v2/tasks/{task_id}")
1750            }
1751
1752            // Node Search API (V1)
1753            WikiApi::SearchNodes => "/open-apis/wiki/v1/nodes/search".to_string(),
1754        }
1755    }
1756}
1757
1758/// Sheets API v3 端点枚举
1759/// 对应 meta.project = sheets, meta.version = v3
1760#[derive(Debug, Clone, PartialEq)]
1761pub enum SheetsApiV3 {
1762    // =====================
1763    // spreadsheet
1764    // =====================
1765    /// 创建电子表格
1766    CreateSpreadsheet,
1767    /// 获取电子表格信息
1768    GetSpreadsheet(String), // spreadsheet_token
1769    /// 修改电子表格属性
1770    PatchSpreadsheet(String), // spreadsheet_token
1771
1772    // =====================
1773    // spreadsheet.sheet
1774    // =====================
1775    /// 获取工作表列表
1776    QuerySheets(String), // spreadsheet_token
1777    /// 查询工作表
1778    GetSheet(String, String), // (spreadsheet_token, sheet_id)
1779    /// 移动行列
1780    MoveDimension(String, String), // (spreadsheet_token, sheet_id)
1781    /// 查找单元格
1782    FindCells(String, String), // (spreadsheet_token, sheet_id)
1783    /// 替换单元格
1784    ReplaceCells(String, String), // (spreadsheet_token, sheet_id)
1785
1786    // =====================
1787    // spreadsheet.sheet.filter
1788    // =====================
1789    /// 创建筛选
1790    CreateFilter(String, String), // (spreadsheet_token, sheet_id)
1791    /// 更新筛选
1792    UpdateFilter(String, String), // (spreadsheet_token, sheet_id)
1793    /// 获取筛选
1794    GetFilter(String, String), // (spreadsheet_token, sheet_id)
1795    /// 删除筛选
1796    DeleteFilter(String, String), // (spreadsheet_token, sheet_id)
1797
1798    // =====================
1799    // spreadsheet.sheet.filter_view
1800    // =====================
1801    /// 创建筛选视图
1802    CreateFilterView(String, String), // (spreadsheet_token, sheet_id)
1803    /// 查询筛选视图
1804    QueryFilterViews(String, String), // (spreadsheet_token, sheet_id)
1805    /// 获取筛选视图
1806    GetFilterView(String, String, String), // (spreadsheet_token, sheet_id, filter_view_id)
1807    /// 更新筛选视图
1808    PatchFilterView(String, String, String), // (spreadsheet_token, sheet_id, filter_view_id)
1809    /// 删除筛选视图
1810    DeleteFilterView(String, String, String), // (spreadsheet_token, sheet_id, filter_view_id)
1811
1812    // =====================
1813    // spreadsheet.sheet.filter_view.condition
1814    // =====================
1815    /// 创建筛选条件
1816    CreateFilterCondition(String, String, String), // (spreadsheet_token, sheet_id, filter_view_id)
1817    /// 查询筛选条件
1818    QueryFilterConditions(String, String, String), // (spreadsheet_token, sheet_id, filter_view_id)
1819    /// 获取筛选条件
1820    GetFilterCondition(String, String, String, String), // (spreadsheet_token, sheet_id, filter_view_id, condition_id)
1821    /// 更新筛选条件
1822    UpdateFilterCondition(String, String, String, String), // (spreadsheet_token, sheet_id, filter_view_id, condition_id)
1823    /// 删除筛选条件
1824    DeleteFilterCondition(String, String, String, String), // (spreadsheet_token, sheet_id, filter_view_id, condition_id)
1825
1826    // =====================
1827    // spreadsheet.sheet.float_image
1828    // =====================
1829    /// 创建浮动图片
1830    CreateFloatImage(String, String), // (spreadsheet_token, sheet_id)
1831    /// 查询浮动图片
1832    QueryFloatImages(String, String), // (spreadsheet_token, sheet_id)
1833    /// 获取浮动图片
1834    GetFloatImage(String, String, String), // (spreadsheet_token, sheet_id, float_image_id)
1835    /// 更新浮动图片
1836    PatchFloatImage(String, String, String), // (spreadsheet_token, sheet_id, float_image_id)
1837    /// 删除浮动图片
1838    DeleteFloatImage(String, String, String), // (spreadsheet_token, sheet_id, float_image_id)
1839}
1840
1841impl SheetsApiV3 {
1842    /// 生成对应的 URL
1843    pub fn to_url(&self) -> String {
1844        match self {
1845            SheetsApiV3::CreateSpreadsheet => "/open-apis/sheets/v3/spreadsheets".to_string(),
1846            SheetsApiV3::GetSpreadsheet(spreadsheet_token) => {
1847                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}")
1848            }
1849            SheetsApiV3::PatchSpreadsheet(spreadsheet_token) => {
1850                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}")
1851            }
1852
1853            SheetsApiV3::QuerySheets(spreadsheet_token) => {
1854                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/query")
1855            }
1856            SheetsApiV3::GetSheet(spreadsheet_token, sheet_id) => {
1857                format!("/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}")
1858            }
1859            SheetsApiV3::MoveDimension(spreadsheet_token, sheet_id) => format!(
1860                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/move_dimension"
1861            ),
1862            SheetsApiV3::FindCells(spreadsheet_token, sheet_id) => format!(
1863                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/find"
1864            ),
1865            SheetsApiV3::ReplaceCells(spreadsheet_token, sheet_id) => format!(
1866                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/replace"
1867            ),
1868
1869            SheetsApiV3::CreateFilter(spreadsheet_token, sheet_id)
1870            | SheetsApiV3::UpdateFilter(spreadsheet_token, sheet_id)
1871            | SheetsApiV3::GetFilter(spreadsheet_token, sheet_id)
1872            | SheetsApiV3::DeleteFilter(spreadsheet_token, sheet_id) => format!(
1873                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter"
1874            ),
1875
1876            SheetsApiV3::CreateFilterView(spreadsheet_token, sheet_id) => format!(
1877                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views"
1878            ),
1879            SheetsApiV3::QueryFilterViews(spreadsheet_token, sheet_id) => format!(
1880                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/query"
1881            ),
1882            SheetsApiV3::GetFilterView(spreadsheet_token, sheet_id, filter_view_id)
1883            | SheetsApiV3::PatchFilterView(spreadsheet_token, sheet_id, filter_view_id)
1884            | SheetsApiV3::DeleteFilterView(spreadsheet_token, sheet_id, filter_view_id) => {
1885                format!(
1886                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}"
1887                )
1888            }
1889
1890            SheetsApiV3::CreateFilterCondition(spreadsheet_token, sheet_id, filter_view_id) => {
1891                format!(
1892                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions"
1893                )
1894            }
1895            SheetsApiV3::QueryFilterConditions(spreadsheet_token, sheet_id, filter_view_id) => {
1896                format!(
1897                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions/query"
1898                )
1899            }
1900            SheetsApiV3::GetFilterCondition(
1901                spreadsheet_token,
1902                sheet_id,
1903                filter_view_id,
1904                condition_id,
1905            )
1906            | SheetsApiV3::UpdateFilterCondition(
1907                spreadsheet_token,
1908                sheet_id,
1909                filter_view_id,
1910                condition_id,
1911            )
1912            | SheetsApiV3::DeleteFilterCondition(
1913                spreadsheet_token,
1914                sheet_id,
1915                filter_view_id,
1916                condition_id,
1917            ) => format!(
1918                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/filter_views/{filter_view_id}/conditions/{condition_id}"
1919            ),
1920
1921            SheetsApiV3::CreateFloatImage(spreadsheet_token, sheet_id) => format!(
1922                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images"
1923            ),
1924            SheetsApiV3::QueryFloatImages(spreadsheet_token, sheet_id) => format!(
1925                "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images/query"
1926            ),
1927            SheetsApiV3::GetFloatImage(spreadsheet_token, sheet_id, float_image_id)
1928            | SheetsApiV3::PatchFloatImage(spreadsheet_token, sheet_id, float_image_id)
1929            | SheetsApiV3::DeleteFloatImage(spreadsheet_token, sheet_id, float_image_id) => {
1930                format!(
1931                    "/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/float_images/{float_image_id}"
1932                )
1933            }
1934        }
1935    }
1936}
1937
1938// Sheets API v3 端点
1939/// 公开项说明。
1940pub const SHEETS_API_V3: &str = "/open-apis/sheets/v3";
1941
1942// ============================================================================
1943// Baike API v1 端点定义
1944// ============================================================================
1945
1946/// Baike知识库 API v1 端点
1947#[derive(Debug, Clone, PartialEq)]
1948pub enum BaikeApiV1 {
1949    /// 草稿管理
1950    DraftCreate,
1951    /// 公开项说明。
1952    DraftUpdate(String), // draft_id
1953
1954    /// 词条管理
1955    EntityCreate,
1956    /// 公开项说明。
1957    EntityUpdate(String), // entity_id
1958    /// 公开项说明。
1959    EntityGet(String), // entity_id
1960    /// 公开项说明。
1961    EntityDelete(String), // entity_id
1962    /// 公开项说明。
1963    EntityList,
1964    /// 公开项说明。
1965    EntityMatch,
1966    /// 公开项说明。
1967    EntitySearch,
1968    /// 公开项说明。
1969    EntityHighlight,
1970    /// 公开项说明。
1971    EntityExtract,
1972
1973    /// 分类管理
1974    ClassificationList,
1975
1976    /// 文件管理
1977    FileUpload,
1978    /// 公开项说明。
1979    FileDownload(String), // file_token
1980}
1981
1982impl BaikeApiV1 {
1983    /// 提供 `to_url` 能力。
1984    pub fn to_url(&self) -> String {
1985        match self {
1986            BaikeApiV1::DraftCreate => "/open-apis/baike/v1/drafts".to_string(),
1987            BaikeApiV1::DraftUpdate(draft_id) => {
1988                format!("/open-apis/baike/v1/drafts/{draft_id}")
1989            }
1990            BaikeApiV1::EntityCreate => "/open-apis/baike/v1/entities".to_string(),
1991            BaikeApiV1::EntityUpdate(entity_id) => {
1992                format!("/open-apis/baike/v1/entities/{entity_id}")
1993            }
1994            BaikeApiV1::EntityGet(entity_id) => {
1995                format!("/open-apis/baike/v1/entities/{entity_id}")
1996            }
1997            BaikeApiV1::EntityDelete(entity_id) => {
1998                format!("/open-apis/baike/v1/entities/{entity_id}")
1999            }
2000            BaikeApiV1::EntityList => "/open-apis/baike/v1/entities".to_string(),
2001            BaikeApiV1::EntityMatch => "/open-apis/baike/v1/entities/match".to_string(),
2002            BaikeApiV1::EntitySearch => "/open-apis/baike/v1/entities/search".to_string(),
2003            BaikeApiV1::EntityHighlight => "/open-apis/baike/v1/entities/highlight".to_string(),
2004            BaikeApiV1::EntityExtract => "/open-apis/baike/v1/entities/extract".to_string(),
2005            BaikeApiV1::ClassificationList => "/open-apis/baike/v1/classifications".to_string(),
2006            BaikeApiV1::FileUpload => "/open-apis/baike/v1/files/upload".to_string(),
2007            BaikeApiV1::FileDownload(file_token) => {
2008                format!("/open-apis/baike/v1/files/{file_token}/download")
2009            }
2010        }
2011    }
2012}
2013
2014// Baike API v1 端点
2015/// 公开项说明。
2016pub const BAIKE_API_V1: &str = "/open-apis/baike/v1";
2017
2018// ============================================================================
2019// Lingo API v1 端点定义
2020// ============================================================================
2021
2022/// Lingo语言服务 API v1 端点
2023#[derive(Debug, Clone, PartialEq)]
2024pub enum LingoApiV1 {
2025    /// 草稿管理
2026    DraftCreate,
2027    /// 公开项说明。
2028    DraftUpdate(String), // draft_id
2029
2030    /// 词条管理
2031    EntityCreate,
2032    /// 公开项说明。
2033    EntityUpdate(String), // entity_id
2034    /// 公开项说明。
2035    EntityDelete(String), // entity_id
2036    /// 公开项说明。
2037    EntityGet(String), // entity_id
2038    /// 公开项说明。
2039    EntityList,
2040    /// 公开项说明。
2041    EntityMatch,
2042    /// 公开项说明。
2043    EntitySearch,
2044    /// 公开项说明。
2045    EntityHighlight,
2046    /// 公开项说明。
2047    EntityBatchGet,
2048    /// 公开项说明。
2049    EntityBatchUpdate,
2050    /// 公开项说明。
2051    EntitySearchRecommend,
2052    /// 公开项说明。
2053    EntityHistoryGet(String), // entity_id
2054    /// 公开项说明。
2055    EntityHistoryList,
2056
2057    /// 分类管理
2058    ClassificationList,
2059
2060    /// 词库管理
2061    RepoList,
2062
2063    /// 文件管理
2064    FileUpload,
2065    /// 公开项说明。
2066    FileDownload(String), // file_token
2067
2068    /// 智能处理
2069    GenerateSummary,
2070    /// 公开项说明。
2071    ExtractKeywords,
2072    /// 公开项说明。
2073    TranslateText,
2074}
2075
2076impl LingoApiV1 {
2077    /// 提供 `to_url` 能力。
2078    pub fn to_url(&self) -> String {
2079        match self {
2080            LingoApiV1::DraftCreate => "/open-apis/lingo/v1/drafts".to_string(),
2081            LingoApiV1::DraftUpdate(draft_id) => {
2082                format!("/open-apis/lingo/v1/drafts/{draft_id}")
2083            }
2084            LingoApiV1::EntityCreate => "/open-apis/lingo/v1/entities".to_string(),
2085            LingoApiV1::EntityUpdate(entity_id) => {
2086                format!("/open-apis/lingo/v1/entities/{entity_id}")
2087            }
2088            LingoApiV1::EntityDelete(entity_id) => {
2089                format!("/open-apis/lingo/v1/entities/{entity_id}")
2090            }
2091            LingoApiV1::EntityGet(entity_id) => {
2092                format!("/open-apis/lingo/v1/entities/{entity_id}")
2093            }
2094            LingoApiV1::EntityList => "/open-apis/lingo/v1/entities".to_string(),
2095            LingoApiV1::EntityMatch => "/open-apis/lingo/v1/entities/match".to_string(),
2096            LingoApiV1::EntitySearch => "/open-apis/lingo/v1/entities/search".to_string(),
2097            LingoApiV1::EntityHighlight => "/open-apis/lingo/v1/entities/highlight".to_string(),
2098            LingoApiV1::EntityBatchGet => "/open-apis/lingo/v1/entities:batchGet".to_string(),
2099            LingoApiV1::EntityBatchUpdate => "/open-apis/lingo/v1/entities:batchUpdate".to_string(),
2100            LingoApiV1::EntitySearchRecommend => {
2101                "/open-apis/lingo/v1/entities:searchRecommend".to_string()
2102            }
2103            LingoApiV1::EntityHistoryGet(entity_id) => {
2104                format!("/open-apis/lingo/v1/entities/{entity_id}/history")
2105            }
2106            LingoApiV1::EntityHistoryList => "/open-apis/lingo/v1/entityHistory".to_string(),
2107            LingoApiV1::ClassificationList => "/open-apis/lingo/v1/classifications".to_string(),
2108            LingoApiV1::RepoList => "/open-apis/lingo/v1/repos".to_string(),
2109            LingoApiV1::FileUpload => "/open-apis/lingo/v1/files/upload".to_string(),
2110            LingoApiV1::FileDownload(file_token) => {
2111                format!("/open-apis/lingo/v1/files/{file_token}/download")
2112            }
2113            LingoApiV1::GenerateSummary => "/open-apis/lingo/v1/text:generateSummary".to_string(),
2114            LingoApiV1::ExtractKeywords => "/open-apis/lingo/v1/text:extractKeywords".to_string(),
2115            LingoApiV1::TranslateText => "/open-apis/lingo/v1/text:translate".to_string(),
2116        }
2117    }
2118}
2119
2120// Lingo API v1 端点
2121/// 公开项说明。
2122pub const LINGO_API_V1: &str = "/open-apis/lingo/v1";
2123
2124#[cfg(test)]
2125mod tests {
2126    use super::*;
2127
2128    // ========== BaseApiV2 Tests ==========
2129    #[test]
2130    fn test_base_api_v2_role_create() {
2131        let endpoint = BaseApiV2::RoleCreate("app_token_123".to_string());
2132        assert_eq!(
2133            endpoint.to_url(),
2134            "/open-apis/base/v2/apps/app_token_123/roles"
2135        );
2136    }
2137
2138    #[test]
2139    fn test_base_api_v2_role_update() {
2140        let endpoint =
2141            BaseApiV2::RoleUpdate("app_token_123".to_string(), "role_id_456".to_string());
2142        assert_eq!(
2143            endpoint.to_url(),
2144            "/open-apis/base/v2/apps/app_token_123/roles/role_id_456"
2145        );
2146    }
2147
2148    #[test]
2149    fn test_base_api_v2_role_list() {
2150        let endpoint = BaseApiV2::RoleList("app_token_123".to_string());
2151        assert_eq!(
2152            endpoint.to_url(),
2153            "/open-apis/base/v2/apps/app_token_123/roles"
2154        );
2155    }
2156
2157    #[test]
2158    fn test_base_api_v2_with_special_chars() {
2159        let endpoint = BaseApiV2::RoleCreate("app-token_123".to_string());
2160        assert!(endpoint.to_url().contains("app-token_123"));
2161    }
2162
2163    // ========== BitableApiV1 Tests ==========
2164    #[test]
2165    fn test_bitable_api_v1_app_create() {
2166        let endpoint = BitableApiV1::AppCreate;
2167        assert_eq!(endpoint.to_url(), "/open-apis/bitable/v1/apps");
2168    }
2169
2170    #[test]
2171    fn test_bitable_api_v1_app_copy() {
2172        let endpoint = BitableApiV1::AppCopy("app_token_123".to_string());
2173        assert_eq!(
2174            endpoint.to_url(),
2175            "/open-apis/bitable/v1/apps/app_token_123/copy"
2176        );
2177    }
2178
2179    #[test]
2180    fn test_bitable_api_v1_table_create() {
2181        let endpoint = BitableApiV1::TableCreate("app_token_123".to_string());
2182        assert_eq!(
2183            endpoint.to_url(),
2184            "/open-apis/bitable/v1/apps/app_token_123/tables"
2185        );
2186    }
2187
2188    #[test]
2189    fn test_bitable_api_v1_record_create() {
2190        let endpoint =
2191            BitableApiV1::RecordCreate("app_token_123".to_string(), "table_id_456".to_string());
2192        assert_eq!(
2193            endpoint.to_url(),
2194            "/open-apis/bitable/v1/apps/app_token_123/tables/table_id_456/records"
2195        );
2196    }
2197
2198    #[test]
2199    fn test_bitable_api_v1_field_create() {
2200        let endpoint =
2201            BitableApiV1::FieldCreate("app_token_123".to_string(), "table_id_456".to_string());
2202        assert_eq!(
2203            endpoint.to_url(),
2204            "/open-apis/bitable/v1/apps/app_token_123/tables/table_id_456/fields"
2205        );
2206    }
2207
2208    #[test]
2209    fn test_bitable_api_v1_block_workflow_list() {
2210        let endpoint = BitableApiV1::BlockWorkflowList("app_token_123".to_string());
2211        assert_eq!(
2212            endpoint.to_url(),
2213            "/open-apis/bitable/v1/apps/app_token_123/block_workflows"
2214        );
2215    }
2216
2217    #[test]
2218    fn test_bitable_api_v1_field_group_create() {
2219        let endpoint =
2220            BitableApiV1::FieldGroupCreate("app_token_123".to_string(), "table_id_456".to_string());
2221        assert_eq!(
2222            endpoint.to_url(),
2223            "/open-apis/bitable/v1/apps/app_token_123/tables/table_id_456/field_groups"
2224        );
2225    }
2226
2227    #[test]
2228    fn test_bitable_api_v1_form_upgrade() {
2229        let endpoint = BitableApiV1::FormUpgrade(
2230            "app_token_123".to_string(),
2231            "table_id_456".to_string(),
2232            "form_id_789".to_string(),
2233        );
2234        assert_eq!(
2235            endpoint.to_url(),
2236            "/open-apis/bitable/v1/apps/app_token_123/tables/table_id_456/forms/form_id_789/upgrade"
2237        );
2238    }
2239
2240    #[test]
2241    fn test_bitable_api_v1_view_create() {
2242        let endpoint =
2243            BitableApiV1::ViewCreate("app_token_123".to_string(), "table_id_456".to_string());
2244        assert_eq!(
2245            endpoint.to_url(),
2246            "/open-apis/bitable/v1/apps/app_token_123/tables/table_id_456/views"
2247        );
2248    }
2249
2250    #[test]
2251    fn test_bitable_api_v1_form_get() {
2252        let endpoint = BitableApiV1::FormGet(
2253            "app_token_123".to_string(),
2254            "table_id_456".to_string(),
2255            "form_id_789".to_string(),
2256        );
2257        assert_eq!(
2258            endpoint.to_url(),
2259            "/open-apis/bitable/v1/apps/app_token_123/tables/table_id_456/forms/form_id_789"
2260        );
2261    }
2262
2263    #[test]
2264    fn test_bitable_api_v1_role_member_create() {
2265        let endpoint =
2266            BitableApiV1::RoleMemberCreate("app_token_123".to_string(), "role_id_456".to_string());
2267        assert_eq!(
2268            endpoint.to_url(),
2269            "/open-apis/bitable/v1/apps/app_token_123/roles/role_id_456/members"
2270        );
2271    }
2272
2273    #[test]
2274    fn test_bitable_api_v1_batch_operations() {
2275        let endpoint = BitableApiV1::TableBatchCreate("app_token_123".to_string());
2276        assert!(endpoint.to_url().contains("batch_create"));
2277
2278        let endpoint = BitableApiV1::RecordBatchDelete(
2279            "app_token_123".to_string(),
2280            "table_id_456".to_string(),
2281        );
2282        assert!(endpoint.to_url().contains("batch_delete"));
2283    }
2284
2285    // ========== MinutesApiV1 Tests ==========
2286    #[test]
2287    fn test_minutes_api_v1_get() {
2288        let endpoint = MinutesApiV1::Get("minute_token_123".to_string());
2289        assert_eq!(
2290            endpoint.to_url(),
2291            "/open-apis/minutes/v1/minutes/minute_token_123"
2292        );
2293    }
2294
2295    #[test]
2296    fn test_minutes_api_v1_media_get() {
2297        let endpoint = MinutesApiV1::MediaGet("minute_token_123".to_string());
2298        assert_eq!(
2299            endpoint.to_url(),
2300            "/open-apis/minutes/v1/minutes/minute_token_123/media"
2301        );
2302    }
2303
2304    #[test]
2305    fn test_minutes_api_v1_transcript_get() {
2306        let endpoint = MinutesApiV1::TranscriptGet("minute_token_123".to_string());
2307        assert_eq!(
2308            endpoint.to_url(),
2309            "/open-apis/minutes/v1/minutes/minute_token_123/transcript"
2310        );
2311    }
2312
2313    #[test]
2314    fn test_minutes_api_v1_statistics_get() {
2315        let endpoint = MinutesApiV1::StatisticsGet("minute_token_123".to_string());
2316        assert_eq!(
2317            endpoint.to_url(),
2318            "/open-apis/minutes/v1/minutes/minute_token_123/statistics"
2319        );
2320    }
2321
2322    #[test]
2323    fn minute_subscription_issue_194_endpoints() {
2324        assert_eq!(
2325            MinutesApiV1::Subscription.to_url(),
2326            "/open-apis/minutes/v1/minutes/subscription"
2327        );
2328        assert_eq!(
2329            MinutesApiV1::Unsubscription.to_url(),
2330            "/open-apis/minutes/v1/minutes/unsubscription"
2331        );
2332    }
2333
2334    // ========== WikiApiV1 Tests ==========
2335    #[test]
2336    fn test_wiki_api_v1_node_search() {
2337        let endpoint = WikiApiV1::NodeSearch;
2338        assert_eq!(endpoint.to_url(), "/open-apis/wiki/v1/nodes/search");
2339    }
2340
2341    // ========== DocsApiV1 Tests ==========
2342    #[test]
2343    fn test_docs_api_v1_content_get() {
2344        let endpoint = DocsApiV1::ContentGet;
2345        assert_eq!(endpoint.to_url(), "/open-apis/docs/v1/content");
2346    }
2347
2348    // ========== DocxApiV1 Tests ==========
2349    #[test]
2350    fn test_docx_api_v1_document_create() {
2351        let endpoint = DocxApiV1::DocumentCreate;
2352        assert_eq!(endpoint.to_url(), "/open-apis/docx/v1/documents");
2353    }
2354
2355    #[test]
2356    fn test_docx_api_v1_document_get() {
2357        let endpoint = DocxApiV1::DocumentGet("doc_id_123".to_string());
2358        assert_eq!(endpoint.to_url(), "/open-apis/docx/v1/documents/doc_id_123");
2359    }
2360
2361    #[test]
2362    fn test_docx_api_v1_document_block_list() {
2363        let endpoint = DocxApiV1::DocumentBlockList("doc_id_123".to_string());
2364        assert_eq!(
2365            endpoint.to_url(),
2366            "/open-apis/docx/v1/documents/doc_id_123/blocks"
2367        );
2368    }
2369
2370    #[test]
2371    fn test_docx_api_v1_chat_announcement_get() {
2372        let endpoint = DocxApiV1::ChatAnnouncementGet("chat_id_123".to_string());
2373        assert_eq!(
2374            endpoint.to_url(),
2375            "/open-apis/docx/v1/chats/chat_id_123/announcement"
2376        );
2377    }
2378
2379    #[test]
2380    fn test_docx_api_v1_document_convert() {
2381        let endpoint = DocxApiV1::DocumentConvert;
2382        assert_eq!(
2383            endpoint.to_url(),
2384            "/open-apis/docx/documents/blocks/convert"
2385        );
2386    }
2387
2388    #[test]
2389    fn test_docx_api_v1_document_block_children_create() {
2390        let endpoint = DocxApiV1::DocumentBlockChildrenCreate(
2391            "doc_id_123".to_string(),
2392            "block_id_456".to_string(),
2393        );
2394        assert_eq!(
2395            endpoint.to_url(),
2396            "/open-apis/docx/v1/documents/doc_id_123/blocks/block_id_456/children"
2397        );
2398    }
2399
2400    // ========== WikiApiV2 Tests ==========
2401    #[test]
2402    fn test_wiki_api_v2_space_list() {
2403        let endpoint = WikiApiV2::SpaceList;
2404        assert_eq!(endpoint.to_url(), "/open-apis/wiki/v2/spaces");
2405    }
2406
2407    #[test]
2408    fn test_wiki_api_v2_space_get() {
2409        let endpoint = WikiApiV2::SpaceGet("space_id_123".to_string());
2410        assert_eq!(endpoint.to_url(), "/open-apis/wiki/v2/spaces/space_id_123");
2411    }
2412
2413    #[test]
2414    fn test_wiki_api_v2_space_create() {
2415        let endpoint = WikiApiV2::SpaceCreate;
2416        assert_eq!(endpoint.to_url(), "/open-apis/wiki/v2/spaces");
2417    }
2418
2419    #[test]
2420    fn test_wiki_api_v2_space_node_list() {
2421        let endpoint = WikiApiV2::SpaceNodeList("space_id_123".to_string());
2422        assert_eq!(
2423            endpoint.to_url(),
2424            "/open-apis/wiki/v2/spaces/space_id_123/nodes"
2425        );
2426    }
2427
2428    #[test]
2429    fn test_wiki_api_v2_space_member_delete() {
2430        let endpoint =
2431            WikiApiV2::SpaceMemberDelete("space_id_123".to_string(), "member_id_456".to_string());
2432        assert_eq!(
2433            endpoint.to_url(),
2434            "/open-apis/wiki/v2/spaces/space_id_123/members/member_id_456"
2435        );
2436    }
2437
2438    #[test]
2439    fn test_wiki_api_v2_task_get() {
2440        let endpoint = WikiApiV2::TaskGet("task_id_123".to_string());
2441        assert_eq!(endpoint.to_url(), "/open-apis/wiki/v2/tasks/task_id_123");
2442    }
2443
2444    // ========== CcmDocApiOld Tests ==========
2445    #[test]
2446    fn test_ccm_doc_api_old_create() {
2447        let endpoint = CcmDocApiOld::Create;
2448        assert_eq!(endpoint.to_url(), "/open-apis/doc/v2/create");
2449    }
2450
2451    #[test]
2452    fn test_ccm_doc_api_old_meta() {
2453        let endpoint = CcmDocApiOld::Meta("doc_token_123".to_string());
2454        assert_eq!(endpoint.to_url(), "/open-apis/doc/v2/meta/doc_token_123");
2455    }
2456
2457    #[test]
2458    fn test_ccm_doc_api_old_raw_content() {
2459        let endpoint = CcmDocApiOld::RawContent("doc_token_123".to_string());
2460        assert_eq!(
2461            endpoint.to_url(),
2462            "/open-apis/doc/v2/doc_token_123/raw_content"
2463        );
2464    }
2465
2466    #[test]
2467    fn test_ccm_doc_api_old_batch_update() {
2468        let endpoint = CcmDocApiOld::BatchUpdate("doc_token_123".to_string());
2469        assert_eq!(
2470            endpoint.to_url(),
2471            "/open-apis/doc/v2/doc_token_123/batch_update"
2472        );
2473    }
2474
2475    // ========== CcmDocsApiOld Tests ==========
2476    #[test]
2477    fn test_ccm_docs_api_old_search_object() {
2478        let endpoint = CcmDocsApiOld::SearchObject;
2479        assert_eq!(endpoint.to_url(), "/open-apis/suite/docs-api/search/object");
2480    }
2481
2482    #[test]
2483    fn test_ccm_docs_api_old_meta() {
2484        let endpoint = CcmDocsApiOld::Meta;
2485        assert_eq!(endpoint.to_url(), "/open-apis/suite/docs-api/meta");
2486    }
2487
2488    // ========== CcmDriveExplorerApiOld Tests ==========
2489    #[test]
2490    fn test_ccm_drive_explorer_api_old_root_folder_meta() {
2491        let endpoint = CcmDriveExplorerApiOld::RootFolderMeta;
2492        assert_eq!(
2493            endpoint.to_url(),
2494            "/open-apis/drive/explorer/v2/root_folder/meta"
2495        );
2496    }
2497
2498    #[test]
2499    fn test_ccm_drive_explorer_api_old_folder_meta() {
2500        let endpoint = CcmDriveExplorerApiOld::FolderMeta("folder_token_123".to_string());
2501        assert_eq!(
2502            endpoint.to_url(),
2503            "/open-apis/drive/explorer/v2/folder/folder_token_123/meta"
2504        );
2505    }
2506
2507    #[test]
2508    fn test_ccm_drive_explorer_api_old_file_copy() {
2509        let endpoint = CcmDriveExplorerApiOld::FileCopy("file_token_123".to_string());
2510        assert_eq!(
2511            endpoint.to_url(),
2512            "/open-apis/drive/explorer/v2/file/copy/files/file_token_123"
2513        );
2514    }
2515
2516    // ========== CcmDriveExplorerApi Tests ==========
2517    #[test]
2518    fn test_ccm_drive_explorer_api_root_folder_meta() {
2519        let endpoint = CcmDriveExplorerApi::RootFolderMeta;
2520        assert_eq!(
2521            endpoint.to_url(),
2522            "/open-apis/drive/v1/explorer/root_folder/meta"
2523        );
2524    }
2525
2526    #[test]
2527    fn test_ccm_drive_explorer_api_folder_meta() {
2528        let endpoint = CcmDriveExplorerApi::FolderMeta("folder_token_123".to_string());
2529        assert_eq!(
2530            endpoint.to_url(),
2531            "/open-apis/drive/v1/explorer/folder/folder_token_123/meta"
2532        );
2533    }
2534
2535    #[test]
2536    fn test_ccm_drive_explorer_api_folder() {
2537        let endpoint = CcmDriveExplorerApi::Folder;
2538        assert_eq!(endpoint.to_url(), "/open-apis/drive/v1/explorer/folder");
2539    }
2540
2541    #[test]
2542    fn test_ccm_drive_explorer_api_to_url_with_params() {
2543        let endpoint = CcmDriveExplorerApi::RootFolderMeta;
2544        let params = vec![("key", "value".to_string())];
2545        let url = endpoint.to_url_with_params(&params);
2546        assert!(url.contains("?"));
2547        assert!(url.contains("key=value"));
2548    }
2549
2550    #[test]
2551    fn test_ccm_drive_explorer_api_to_url_with_empty_params() {
2552        let endpoint = CcmDriveExplorerApi::RootFolderMeta;
2553        let params: Vec<(&str, String)> = vec![];
2554        let url = endpoint.to_url_with_params(&params);
2555        assert!(!url.contains("?"));
2556    }
2557
2558    #[test]
2559    fn test_ccm_drive_explorer_api_to_url_with_special_chars() {
2560        let endpoint = CcmDriveExplorerApi::RootFolderMeta;
2561        let params = vec![("query", "hello world".to_string())];
2562        let url = endpoint.to_url_with_params(&params);
2563        assert!(url.contains("%20"));
2564    }
2565
2566    // ========== PermissionApi Tests ==========
2567    #[test]
2568    fn test_permission_api_member_permitted() {
2569        let endpoint = PermissionApi::MemberPermitted;
2570        assert_eq!(
2571            endpoint.to_url(),
2572            "/open-apis/drive/v1/permission/member/permitted"
2573        );
2574    }
2575
2576    #[test]
2577    fn test_permission_api_member_transfer() {
2578        let endpoint = PermissionApi::MemberTransfer;
2579        assert_eq!(
2580            endpoint.to_url(),
2581            "/open-apis/drive/v1/permission/member/transfer"
2582        );
2583    }
2584
2585    #[test]
2586    fn test_permission_api_public() {
2587        let endpoint = PermissionApi::Public;
2588        assert_eq!(
2589            endpoint.to_url(),
2590            "/open-apis/drive/v1/permission/v2/public/"
2591        );
2592    }
2593
2594    // ========== PermissionApiOld Tests ==========
2595    #[test]
2596    fn test_permission_api_old_member_permitted() {
2597        let endpoint = PermissionApiOld::MemberPermitted;
2598        assert_eq!(
2599            endpoint.to_url(),
2600            "/open-apis/drive/v1/permission/member/permitted"
2601        );
2602    }
2603
2604    #[test]
2605    fn test_permission_api_old_public() {
2606        let endpoint = PermissionApiOld::Public;
2607        assert_eq!(
2608            endpoint.to_url(),
2609            "/open-apis/drive/v1/permission/v2/public/"
2610        );
2611    }
2612}