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