rust_cnb/
releases.rs

1//! Releases API 客户端
2
3use crate::error::{ApiError, Result};
4use reqwest::Client;
5use serde_json::Value;
6use url::Url;
7
8/// Releases API 客户端
9pub struct ReleasesClient {
10    base_url: String,
11    client: Client,
12}
13
14impl ReleasesClient {
15    /// 创建新的 Releases 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    /// 查询 latest release。Query the latest release.
27    pub async fn get_repo_releases_latest(
28        &self,
29        repo: String,
30    ) -> Result<Value> {
31        let path = format!("/{}/-/releases/latest", repo);
32        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
33        
34
35                let request = self.client.request(
36            reqwest::Method::GET,
37            url
38        );
39        
40
41
42
43        let response = request.send().await?;
44        
45        if response.status().is_success() {
46            let json: Value = response.json().await?;
47            Ok(json)
48        } else {
49            Err(ApiError::HttpError(response.status().as_u16()))
50        }
51    }
52
53    /// 新增一个 Release asset。Create a release asset.
54    pub async fn post_repo_releases_release_id_asset_upload_url(
55        &self,
56        repo: String,
57        release_id: String,
58        create_release_asset_upload_url_form: serde_json::Value,
59    ) -> Result<Value> {
60        let path = format!("/{}/-/releases/{}/asset-upload-url", repo, release_id);
61        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
62        
63
64        
65        let mut request = self.client.request(
66            reqwest::Method::POST,
67            url
68        );
69
70
71
72        request = request.json(&create_release_asset_upload_url_form);
73
74        let response = request.send().await?;
75        
76        if response.status().is_success() {
77            let json: Value = response.json().await?;
78            Ok(json)
79        } else {
80            Err(ApiError::HttpError(response.status().as_u16()))
81        }
82    }
83
84    /// 根据 id	查询指定 release, 包含附件信息。Get a release by id, include assets information.
85    pub async fn get_repo_releases_release_id(
86        &self,
87        repo: String,
88        release_id: String,
89    ) -> Result<Value> {
90        let path = format!("/{}/-/releases/{}", repo, release_id);
91        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
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    /// 删除指定的 release。Delete a release.
113    pub async fn delete_repo_releases_release_id(
114        &self,
115        repo: String,
116        release_id: String,
117    ) -> Result<Value> {
118        let path = format!("/{}/-/releases/{}", repo, release_id);
119        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
120        
121
122                let request = self.client.request(
123            reqwest::Method::DELETE,
124            url
125        );
126        
127
128
129
130        let response = request.send().await?;
131        
132        if response.status().is_success() {
133            let json: Value = response.json().await?;
134            Ok(json)
135        } else {
136            Err(ApiError::HttpError(response.status().as_u16()))
137        }
138    }
139
140    /// 更新 release。Update a release.
141    pub async fn patch_repo_releases_release_id(
142        &self,
143        repo: String,
144        release_id: String,
145        patch_release_form: serde_json::Value,
146    ) -> Result<Value> {
147        let path = format!("/{}/-/releases/{}", repo, release_id);
148        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
149        
150
151        
152        let mut request = self.client.request(
153            reqwest::Method::PATCH,
154            url
155        );
156
157
158
159        request = request.json(&patch_release_form);
160
161        let response = request.send().await?;
162        
163        if response.status().is_success() {
164            let json: Value = response.json().await?;
165            Ok(json)
166        } else {
167            Err(ApiError::HttpError(response.status().as_u16()))
168        }
169    }
170
171    /// 查询指定的 release asset。Get the specified release asset.
172    pub async fn get_repo_releases_release_id_assets_asset_id(
173        &self,
174        repo: String,
175        release_id: String,
176        asset_id: String,
177    ) -> Result<Value> {
178        let path = format!("/{}/-/releases/{}/assets/{}", repo, release_id, asset_id);
179        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
180        
181
182                let request = self.client.request(
183            reqwest::Method::GET,
184            url
185        );
186        
187
188
189
190        let response = request.send().await?;
191        
192        if response.status().is_success() {
193            let json: Value = response.json().await?;
194            Ok(json)
195        } else {
196            Err(ApiError::HttpError(response.status().as_u16()))
197        }
198    }
199
200    /// 删除指定的 release asset。Delete the specified release asset.
201    pub async fn delete_repo_releases_release_id_assets_asset_id(
202        &self,
203        repo: String,
204        release_id: String,
205        asset_id: String,
206    ) -> Result<Value> {
207        let path = format!("/{}/-/releases/{}/assets/{}", repo, release_id, asset_id);
208        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
209        
210
211                let request = self.client.request(
212            reqwest::Method::DELETE,
213            url
214        );
215        
216
217
218
219        let response = request.send().await?;
220        
221        if response.status().is_success() {
222            let json: Value = response.json().await?;
223            Ok(json)
224        } else {
225            Err(ApiError::HttpError(response.status().as_u16()))
226        }
227    }
228
229    /// 通过 tag 查询指定 release,包含附件信息。Get a release by tag, include assets information.
230    pub async fn get_repo_releases_tags_tag(
231        &self,
232        repo: String,
233        tag: String,
234    ) -> Result<Value> {
235        let path = format!("/{}/-/releases/tags/{}", repo, tag);
236        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
237        
238
239                let request = self.client.request(
240            reqwest::Method::GET,
241            url
242        );
243        
244
245
246
247        let response = request.send().await?;
248        
249        if response.status().is_success() {
250            let json: Value = response.json().await?;
251            Ok(json)
252        } else {
253            Err(ApiError::HttpError(response.status().as_u16()))
254        }
255    }
256
257    /// 确认 Release asset 上传完成。Confirm release asset upload.
258    pub async fn post_repo_releases_release_id_asset_upload_confirmation_upload_token_asset_path(
259        &self,
260        repo: String,
261        release_id: String,
262        token: String,
263        asset_path: String,
264    ) -> Result<Value> {
265        let path = format!("/{}/-/releases/{}/asset-upload-confirmation/{}/{}", repo, release_id, token, asset_path);
266        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
267        
268
269                let request = self.client.request(
270            reqwest::Method::POST,
271            url
272        );
273        
274
275
276
277        let response = request.send().await?;
278        
279        if response.status().is_success() {
280            let json: Value = response.json().await?;
281            Ok(json)
282        } else {
283            Err(ApiError::HttpError(response.status().as_u16()))
284        }
285    }
286
287    /// 查询 release 列表。List releases.
288    pub async fn get_repo_releases(
289        &self,
290        repo: String,
291        page: Option<i64>,
292        page_size: Option<i64>,
293    ) -> Result<Value> {
294        let path = format!("/{}/-/releases", repo);
295        let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
296        
297        if let Some(value) = page {
298            url.query_pairs_mut().append_pair("page", &value.to_string());
299        }
300        if let Some(value) = page_size {
301            url.query_pairs_mut().append_pair("page_size", &value.to_string());
302        }
303
304                let request = self.client.request(
305            reqwest::Method::GET,
306            url
307        );
308        
309
310
311
312        let response = request.send().await?;
313        
314        if response.status().is_success() {
315            let json: Value = response.json().await?;
316            Ok(json)
317        } else {
318            Err(ApiError::HttpError(response.status().as_u16()))
319        }
320    }
321
322    /// 新增一个 Release。Create a release.
323    pub async fn post_repo_releases(
324        &self,
325        repo: String,
326        create_release_form: serde_json::Value,
327    ) -> Result<Value> {
328        let path = format!("/{}/-/releases", repo);
329        let url = Url::parse(&format!("{}{}", self.base_url, path))?;
330        
331
332        
333        let mut request = self.client.request(
334            reqwest::Method::POST,
335            url
336        );
337
338
339
340        request = request.json(&create_release_form);
341
342        let response = request.send().await?;
343        
344        if response.status().is_success() {
345            let json: Value = response.json().await?;
346            Ok(json)
347        } else {
348            Err(ApiError::HttpError(response.status().as_u16()))
349        }
350    }
351
352}