rust_cnb/
collaborators.rs

1//! Collaborators API 客户端
2
3use crate::error::{ApiError, Result};
4use reqwest::Client;
5use serde_json::Value;
6use url::Url;
7
8/// Collaborators API 客户端
9pub struct CollaboratorsClient {
10    base_url: String,
11    client: Client,
12}
13
14impl CollaboratorsClient {
15    /// 创建新的 Collaborators API 客户端
16    pub fn new(base_url: String, client: Client) -> Self {
17        Self { base_url, client }
18    }
19
20    /// 设置认证信息
21    pub fn with_auth(self, token: &str) -> Self {
22        // 这里可以扩展认证逻辑
23        self
24    }
25
26    /// 获取指定组织或仓库内的继承成员。List inherited members within specified organization or repository。
27    pub async fn get_repo_inherit_members(
28        &self,
29        repo: String,
30        search: Option<String>,
31        role: Option<String>,
32        page: Option<i64>,
33        page_size: Option<i64>,
34    ) -> Result<Value> {
35        let path = format!("/{}/-/inherit-members", repo);
36        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
37        
38        if let Some(value) = search {
39            url.query_pairs_mut().append_pair("search", &value.to_string());
40        }
41        if let Some(value) = role {
42            url.query_pairs_mut().append_pair("role", &value.to_string());
43        }
44        if let Some(value) = page {
45            url.query_pairs_mut().append_pair("page", &value.to_string());
46        }
47        if let Some(value) = page_size {
48            url.query_pairs_mut().append_pair("page_size", &value.to_string());
49        }
50
51                let request = self.client.request(
52            reqwest::Method::GET,
53            url
54        );
55        
56
57
58
59        let response = request.send().await?;
60        
61        if response.status().is_success() {
62            let json: Value = response.json().await?;
63            Ok(json)
64        } else {
65            Err(ApiError::HttpError(response.status().as_u16()))
66        }
67    }
68
69    /// 获取指定组织或仓库内的继承成员。List inherited members within specified organization or repository。
70    pub async fn get_group_inherit_members(
71        &self,
72        group: String,
73        search: Option<String>,
74        role: Option<String>,
75        page: Option<i64>,
76        page_size: Option<i64>,
77    ) -> Result<Value> {
78        let path = format!("/{}/-/inherit-members", group);
79        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
80        
81        if let Some(value) = search {
82            url.query_pairs_mut().append_pair("search", &value.to_string());
83        }
84        if let Some(value) = role {
85            url.query_pairs_mut().append_pair("role", &value.to_string());
86        }
87        if let Some(value) = page {
88            url.query_pairs_mut().append_pair("page", &value.to_string());
89        }
90        if let Some(value) = page_size {
91            url.query_pairs_mut().append_pair("page_size", &value.to_string());
92        }
93
94                let request = self.client.request(
95            reqwest::Method::GET,
96            url
97        );
98        
99
100
101
102        let response = request.send().await?;
103        
104        if response.status().is_success() {
105            let json: Value = response.json().await?;
106            Ok(json)
107        } else {
108            Err(ApiError::HttpError(response.status().as_u16()))
109        }
110    }
111
112    /// 添加成员。Add members.
113    pub async fn post_group_members_username(
114        &self,
115        group: String,
116        username: String,
117        request_data: serde_json::Value,
118    ) -> Result<Value> {
119        let path = format!("/{}/-/members/{}", group, username);
120        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
121        
122
123        
124        let mut request = self.client.request(
125            reqwest::Method::POST,
126            url
127        );
128
129
130
131        request = request.json(&request_data);
132
133        let response = request.send().await?;
134        
135        if response.status().is_success() {
136            let json: Value = response.json().await?;
137            Ok(json)
138        } else {
139            Err(ApiError::HttpError(response.status().as_u16()))
140        }
141    }
142
143    /// 更新指定组织或仓库内的直接成员权限信息。Update permission information for direct members in specified organization/repository.
144    pub async fn put_group_members_username(
145        &self,
146        group: String,
147        username: String,
148        request_data: serde_json::Value,
149    ) -> Result<Value> {
150        let path = format!("/{}/-/members/{}", group, username);
151        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
152        
153
154        
155        let mut request = self.client.request(
156            reqwest::Method::PUT,
157            url
158        );
159
160
161
162        request = request.json(&request_data);
163
164        let response = request.send().await?;
165        
166        if response.status().is_success() {
167            let json: Value = response.json().await?;
168            Ok(json)
169        } else {
170            Err(ApiError::HttpError(response.status().as_u16()))
171        }
172    }
173
174    /// 删除指定组织或仓库的直接成员。Remove direct members from specified organization/repository.
175    pub async fn delete_group_members_username(
176        &self,
177        group: String,
178        username: String,
179    ) -> Result<Value> {
180        let path = format!("/{}/-/members/{}", group, username);
181        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
182        
183
184                let request = self.client.request(
185            reqwest::Method::DELETE,
186            url
187        );
188        
189
190
191
192        let response = request.send().await?;
193        
194        if response.status().is_success() {
195            let json: Value = response.json().await?;
196            Ok(json)
197        } else {
198            Err(ApiError::HttpError(response.status().as_u16()))
199        }
200    }
201
202    /// 获取指定仓库内的外部贡献者。List external contributors in specified repository.
203    pub async fn get_repo_outside_collaborators(
204        &self,
205        repo: String,
206        page: Option<i64>,
207        page_size: Option<i64>,
208        role: Option<String>,
209        search: Option<String>,
210    ) -> Result<Value> {
211        let path = format!("/{}/-/outside-collaborators", repo);
212        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
213        
214        if let Some(value) = page {
215            url.query_pairs_mut().append_pair("page", &value.to_string());
216        }
217        if let Some(value) = page_size {
218            url.query_pairs_mut().append_pair("page_size", &value.to_string());
219        }
220        if let Some(value) = role {
221            url.query_pairs_mut().append_pair("role", &value.to_string());
222        }
223        if let Some(value) = search {
224            url.query_pairs_mut().append_pair("search", &value.to_string());
225        }
226
227                let request = self.client.request(
228            reqwest::Method::GET,
229            url
230        );
231        
232
233
234
235        let response = request.send().await?;
236        
237        if response.status().is_success() {
238            let json: Value = response.json().await?;
239            Ok(json)
240        } else {
241            Err(ApiError::HttpError(response.status().as_u16()))
242        }
243    }
244
245    /// 添加成员。Add members.
246    pub async fn post_mission_members_username(
247        &self,
248        mission: String,
249        username: String,
250        request_data: serde_json::Value,
251    ) -> Result<Value> {
252        let path = format!("/{}/-/members/{}", mission, username);
253        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
254        
255
256        
257        let mut request = self.client.request(
258            reqwest::Method::POST,
259            url
260        );
261
262
263
264        request = request.json(&request_data);
265
266        let response = request.send().await?;
267        
268        if response.status().is_success() {
269            let json: Value = response.json().await?;
270            Ok(json)
271        } else {
272            Err(ApiError::HttpError(response.status().as_u16()))
273        }
274    }
275
276    /// 更新指定仓库的外部贡献者权限信息。 Update permission information for external contributors in specified repository.
277    pub async fn put_repo_outside_collaborators_username(
278        &self,
279        repo: String,
280        username: String,
281        role: String,
282    ) -> Result<Value> {
283        let path = format!("/{}/-/outside-collaborators/{}", repo, username);
284        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
285        
286        url.query_pairs_mut().append_pair("role", &role.to_string());
287
288                let request = self.client.request(
289            reqwest::Method::PUT,
290            url
291        );
292        
293
294
295
296        let response = request.send().await?;
297        
298        if response.status().is_success() {
299            let json: Value = response.json().await?;
300            Ok(json)
301        } else {
302            Err(ApiError::HttpError(response.status().as_u16()))
303        }
304    }
305
306    /// 删除指定仓库的外部贡献者。Removes external contributors from specified repository.
307    pub async fn delete_repo_outside_collaborators_username(
308        &self,
309        repo: String,
310        username: String,
311    ) -> Result<Value> {
312        let path = format!("/{}/-/outside-collaborators/{}", repo, username);
313        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
314        
315
316                let request = self.client.request(
317            reqwest::Method::DELETE,
318            url
319        );
320        
321
322
323
324        let response = request.send().await?;
325        
326        if response.status().is_success() {
327            let json: Value = response.json().await?;
328            Ok(json)
329        } else {
330            Err(ApiError::HttpError(response.status().as_u16()))
331        }
332    }
333
334    /// 添加成员。Add members.
335    pub async fn post_repo_members_username(
336        &self,
337        repo: String,
338        username: String,
339        request_data: serde_json::Value,
340    ) -> Result<Value> {
341        let path = format!("/{}/-/members/{}", repo, username);
342        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
343        
344
345        
346        let mut request = self.client.request(
347            reqwest::Method::POST,
348            url
349        );
350
351
352
353        request = request.json(&request_data);
354
355        let response = request.send().await?;
356        
357        if response.status().is_success() {
358            let json: Value = response.json().await?;
359            Ok(json)
360        } else {
361            Err(ApiError::HttpError(response.status().as_u16()))
362        }
363    }
364
365    /// 更新指定组织或仓库内的直接成员权限信息。Update permission information for direct members in specified organization/repository.
366    pub async fn put_repo_members_username(
367        &self,
368        repo: String,
369        username: String,
370        request_data: serde_json::Value,
371    ) -> Result<Value> {
372        let path = format!("/{}/-/members/{}", repo, username);
373        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
374        
375
376        
377        let mut request = self.client.request(
378            reqwest::Method::PUT,
379            url
380        );
381
382
383
384        request = request.json(&request_data);
385
386        let response = request.send().await?;
387        
388        if response.status().is_success() {
389            let json: Value = response.json().await?;
390            Ok(json)
391        } else {
392            Err(ApiError::HttpError(response.status().as_u16()))
393        }
394    }
395
396    /// 删除指定组织或仓库的直接成员。Remove direct members from specified organization/repository.
397    pub async fn delete_repo_members_username(
398        &self,
399        repo: String,
400        username: String,
401    ) -> Result<Value> {
402        let path = format!("/{}/-/members/{}", repo, username);
403        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
404        
405
406                let request = self.client.request(
407            reqwest::Method::DELETE,
408            url
409        );
410        
411
412
413
414        let response = request.send().await?;
415        
416        if response.status().is_success() {
417            let json: Value = response.json().await?;
418            Ok(json)
419        } else {
420            Err(ApiError::HttpError(response.status().as_u16()))
421        }
422    }
423
424    /// 获取指定组织或仓库内的所有直接成员。List all direct members within specified organization or repository.
425    pub async fn get_repo_members(
426        &self,
427        repo: String,
428        page: Option<i64>,
429        page_size: Option<i64>,
430        role: Option<String>,
431        search: Option<String>,
432    ) -> Result<Value> {
433        let path = format!("/{}/-/members", repo);
434        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
435        
436        if let Some(value) = page {
437            url.query_pairs_mut().append_pair("page", &value.to_string());
438        }
439        if let Some(value) = page_size {
440            url.query_pairs_mut().append_pair("page_size", &value.to_string());
441        }
442        if let Some(value) = role {
443            url.query_pairs_mut().append_pair("role", &value.to_string());
444        }
445        if let Some(value) = search {
446            url.query_pairs_mut().append_pair("search", &value.to_string());
447        }
448
449                let request = self.client.request(
450            reqwest::Method::GET,
451            url
452        );
453        
454
455
456
457        let response = request.send().await?;
458        
459        if response.status().is_success() {
460            let json: Value = response.json().await?;
461            Ok(json)
462        } else {
463            Err(ApiError::HttpError(response.status().as_u16()))
464        }
465    }
466
467    /// 获取指定仓库内的有效成员列表,包含继承成员。List active members in specified repository including inherited members.
468    pub async fn get_repo_list_members(
469        &self,
470        repo: String,
471        page: Option<i64>,
472        page_size: Option<i64>,
473        role: Option<String>,
474        search: Option<String>,
475        names: Option<String>,
476        order_by: Option<String>,
477        desc: Option<bool>,
478    ) -> Result<Value> {
479        let path = format!("/{}/-/list-members", repo);
480        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
481        
482        if let Some(value) = page {
483            url.query_pairs_mut().append_pair("page", &value.to_string());
484        }
485        if let Some(value) = page_size {
486            url.query_pairs_mut().append_pair("page_size", &value.to_string());
487        }
488        if let Some(value) = role {
489            url.query_pairs_mut().append_pair("role", &value.to_string());
490        }
491        if let Some(value) = search {
492            url.query_pairs_mut().append_pair("search", &value.to_string());
493        }
494        if let Some(value) = names {
495            url.query_pairs_mut().append_pair("names", &value.to_string());
496        }
497        if let Some(value) = order_by {
498            url.query_pairs_mut().append_pair("order_by", &value.to_string());
499        }
500        if let Some(value) = desc {
501            url.query_pairs_mut().append_pair("desc", &value.to_string());
502        }
503
504                let request = self.client.request(
505            reqwest::Method::GET,
506            url
507        );
508        
509
510
511
512        let response = request.send().await?;
513        
514        if response.status().is_success() {
515            let json: Value = response.json().await?;
516            Ok(json)
517        } else {
518            Err(ApiError::HttpError(response.status().as_u16()))
519        }
520    }
521
522    /// 获取指定组织或仓库内的所有直接成员。List all direct members within specified organization or repository.
523    pub async fn get_group_members(
524        &self,
525        group: String,
526        page: Option<i64>,
527        page_size: Option<i64>,
528        role: Option<String>,
529        search: Option<String>,
530    ) -> Result<Value> {
531        let path = format!("/{}/-/members", group);
532        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
533        
534        if let Some(value) = page {
535            url.query_pairs_mut().append_pair("page", &value.to_string());
536        }
537        if let Some(value) = page_size {
538            url.query_pairs_mut().append_pair("page_size", &value.to_string());
539        }
540        if let Some(value) = role {
541            url.query_pairs_mut().append_pair("role", &value.to_string());
542        }
543        if let Some(value) = search {
544            url.query_pairs_mut().append_pair("search", &value.to_string());
545        }
546
547                let request = self.client.request(
548            reqwest::Method::GET,
549            url
550        );
551        
552
553
554
555        let response = request.send().await?;
556        
557        if response.status().is_success() {
558            let json: Value = response.json().await?;
559            Ok(json)
560        } else {
561            Err(ApiError::HttpError(response.status().as_u16()))
562        }
563    }
564
565    /// 添加成员。Add members.
566    pub async fn post_registry_members_username(
567        &self,
568        registry: String,
569        username: String,
570        request_data: serde_json::Value,
571    ) -> Result<Value> {
572        let path = format!("/{}/-/members/{}", registry, username);
573        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
574        
575
576        
577        let mut request = self.client.request(
578            reqwest::Method::POST,
579            url
580        );
581
582
583
584        request = request.json(&request_data);
585
586        let response = request.send().await?;
587        
588        if response.status().is_success() {
589            let json: Value = response.json().await?;
590            Ok(json)
591        } else {
592            Err(ApiError::HttpError(response.status().as_u16()))
593        }
594    }
595
596    /// 获取 top 贡献用户。List the top contributing users
597    pub async fn get_repo_top_activity_users(
598        &self,
599        repo: String,
600        top: Option<i64>,
601    ) -> Result<Value> {
602        let path = format!("/{}/-/top-activity-users", repo);
603        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
604        
605        if let Some(value) = top {
606            url.query_pairs_mut().append_pair("top", &value.to_string());
607        }
608
609                let request = self.client.request(
610            reqwest::Method::GET,
611            url
612        );
613        
614
615
616
617        let response = request.send().await?;
618        
619        if response.status().is_success() {
620            let json: Value = response.json().await?;
621            Ok(json)
622        } else {
623            Err(ApiError::HttpError(response.status().as_u16()))
624        }
625    }
626
627}