1use crate::error::{ApiError, Result};
4use reqwest::Client;
5use serde_json::Value;
6use url::Url;
7
8pub struct IssuesClient {
10 base_url: String,
11 client: Client,
12}
13
14impl IssuesClient {
15 pub fn new(base_url: String, client: Client) -> Self {
17 Self { base_url, client }
18 }
19
20 pub fn with_auth(self, token: &str) -> Self {
22 self
24 }
25
26 pub async fn get_repo_issues_number_assignees_assignee(
28 &self,
29 repo: String,
30 number: String,
31 assignee: String,
32 ) -> Result<Value> {
33 let path = format!("/{}/-/issues/{}/assignees/{}", repo, number, assignee);
34 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
35
36
37 let request = self.client.request(
38 reqwest::Method::GET,
39 url
40 );
41
42
43
44
45 let response = request.send().await?;
46
47 if response.status().is_success() {
48 let json: Value = response.json().await?;
49 Ok(json)
50 } else {
51 Err(ApiError::HttpError(response.status().as_u16()))
52 }
53 }
54
55 pub async fn get_repo_issues_number_comments_comment_id(
57 &self,
58 repo: String,
59 number: String,
60 comment_id: String,
61 ) -> Result<Value> {
62 let path = format!("/{}/-/issues/{}/comments/{}", repo, number, comment_id);
63 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
64
65
66 let request = self.client.request(
67 reqwest::Method::GET,
68 url
69 );
70
71
72
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 pub async fn patch_repo_issues_number_comments_comment_id(
86 &self,
87 repo: String,
88 number: i64,
89 comment_id: i64,
90 patch_issue_comment_form: serde_json::Value,
91 ) -> Result<Value> {
92 let path = format!("/{}/-/issues/{}/comments/{}", repo, number, comment_id);
93 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
94
95
96
97 let mut request = self.client.request(
98 reqwest::Method::PATCH,
99 url
100 );
101
102
103
104 request = request.json(&patch_issue_comment_form);
105
106 let response = request.send().await?;
107
108 if response.status().is_success() {
109 let json: Value = response.json().await?;
110 Ok(json)
111 } else {
112 Err(ApiError::HttpError(response.status().as_u16()))
113 }
114 }
115
116 pub async fn get_repo_issues_number(
118 &self,
119 repo: String,
120 number: i64,
121 ) -> Result<Value> {
122 let path = format!("/{}/-/issues/{}", repo, number);
123 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
124
125
126 let request = self.client.request(
127 reqwest::Method::GET,
128 url
129 );
130
131
132
133
134 let response = request.send().await?;
135
136 if response.status().is_success() {
137 let json: Value = response.json().await?;
138 Ok(json)
139 } else {
140 Err(ApiError::HttpError(response.status().as_u16()))
141 }
142 }
143
144 pub async fn patch_repo_issues_number(
146 &self,
147 repo: String,
148 number: i64,
149 patch_issue_form: serde_json::Value,
150 ) -> Result<Value> {
151 let path = format!("/{}/-/issues/{}", repo, number);
152 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
153
154
155
156 let mut request = self.client.request(
157 reqwest::Method::PATCH,
158 url
159 );
160
161
162
163 request = request.json(&patch_issue_form);
164
165 let response = request.send().await?;
166
167 if response.status().is_success() {
168 let json: Value = response.json().await?;
169 Ok(json)
170 } else {
171 Err(ApiError::HttpError(response.status().as_u16()))
172 }
173 }
174
175 pub async fn get_repo_issues(
177 &self,
178 repo: String,
179 page: Option<i64>,
180 page_size: Option<i64>,
181 state: Option<String>,
182 keyword: Option<String>,
183 priority: Option<String>,
184 labels: Option<String>,
185 authors: Option<String>,
186 assignees: Option<String>,
187 updated_time_begin: Option<String>,
188 updated_time_end: Option<String>,
189 close_time_begin: Option<String>,
190 close_time_end: Option<String>,
191 order_by: Option<String>,
192 ) -> Result<Value> {
193 let path = format!("/{}/-/issues", repo);
194 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
195
196 if let Some(value) = page {
197 url.query_pairs_mut().append_pair("page", &value.to_string());
198 }
199 if let Some(value) = page_size {
200 url.query_pairs_mut().append_pair("page_size", &value.to_string());
201 }
202 if let Some(value) = state {
203 url.query_pairs_mut().append_pair("state", &value.to_string());
204 }
205 if let Some(value) = keyword {
206 url.query_pairs_mut().append_pair("keyword", &value.to_string());
207 }
208 if let Some(value) = priority {
209 url.query_pairs_mut().append_pair("priority", &value.to_string());
210 }
211 if let Some(value) = labels {
212 url.query_pairs_mut().append_pair("labels", &value.to_string());
213 }
214 if let Some(value) = authors {
215 url.query_pairs_mut().append_pair("authors", &value.to_string());
216 }
217 if let Some(value) = assignees {
218 url.query_pairs_mut().append_pair("assignees", &value.to_string());
219 }
220 if let Some(value) = updated_time_begin {
221 url.query_pairs_mut().append_pair("updated_time_begin", &value.to_string());
222 }
223 if let Some(value) = updated_time_end {
224 url.query_pairs_mut().append_pair("updated_time_end", &value.to_string());
225 }
226 if let Some(value) = close_time_begin {
227 url.query_pairs_mut().append_pair("close_time_begin", &value.to_string());
228 }
229 if let Some(value) = close_time_end {
230 url.query_pairs_mut().append_pair("close_time_end", &value.to_string());
231 }
232 if let Some(value) = order_by {
233 url.query_pairs_mut().append_pair("order_by", &value.to_string());
234 }
235
236 let request = self.client.request(
237 reqwest::Method::GET,
238 url
239 );
240
241
242
243
244 let response = request.send().await?;
245
246 if response.status().is_success() {
247 let json: Value = response.json().await?;
248 Ok(json)
249 } else {
250 Err(ApiError::HttpError(response.status().as_u16()))
251 }
252 }
253
254 pub async fn post_repo_issues(
256 &self,
257 repo: String,
258 post_issue_form: serde_json::Value,
259 ) -> Result<Value> {
260 let path = format!("/{}/-/issues", repo);
261 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
262
263
264
265 let mut request = self.client.request(
266 reqwest::Method::POST,
267 url
268 );
269
270
271
272 request = request.json(&post_issue_form);
273
274 let response = request.send().await?;
275
276 if response.status().is_success() {
277 let json: Value = response.json().await?;
278 Ok(json)
279 } else {
280 Err(ApiError::HttpError(response.status().as_u16()))
281 }
282 }
283
284 pub async fn delete_repo_issues_number_labels_name(
286 &self,
287 repo: String,
288 number: i64,
289 name: String,
290 ) -> Result<Value> {
291 let path = format!("/{}/-/issues/{}/labels/{}", repo, number, name);
292 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
293
294
295 let request = self.client.request(
296 reqwest::Method::DELETE,
297 url
298 );
299
300
301
302
303 let response = request.send().await?;
304
305 if response.status().is_success() {
306 let json: Value = response.json().await?;
307 Ok(json)
308 } else {
309 Err(ApiError::HttpError(response.status().as_u16()))
310 }
311 }
312
313 pub async fn get_repo_issues_number_assignees(
315 &self,
316 repo: String,
317 number: String,
318 ) -> Result<Value> {
319 let path = format!("/{}/-/issues/{}/assignees", repo, number);
320 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
321
322
323 let request = self.client.request(
324 reqwest::Method::GET,
325 url
326 );
327
328
329
330
331 let response = request.send().await?;
332
333 if response.status().is_success() {
334 let json: Value = response.json().await?;
335 Ok(json)
336 } else {
337 Err(ApiError::HttpError(response.status().as_u16()))
338 }
339 }
340
341 pub async fn post_repo_issues_number_assignees(
343 &self,
344 repo: String,
345 number: String,
346 post_issue_assignees_form: serde_json::Value,
347 ) -> Result<Value> {
348 let path = format!("/{}/-/issues/{}/assignees", repo, number);
349 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
350
351
352
353 let mut request = self.client.request(
354 reqwest::Method::POST,
355 url
356 );
357
358
359
360 request = request.json(&post_issue_assignees_form);
361
362 let response = request.send().await?;
363
364 if response.status().is_success() {
365 let json: Value = response.json().await?;
366 Ok(json)
367 } else {
368 Err(ApiError::HttpError(response.status().as_u16()))
369 }
370 }
371
372 pub async fn delete_repo_issues_number_assignees(
374 &self,
375 repo: String,
376 number: String,
377 delete_issue_assignees_form: serde_json::Value,
378 ) -> Result<Value> {
379 let path = format!("/{}/-/issues/{}/assignees", repo, number);
380 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
381
382
383
384 let mut request = self.client.request(
385 reqwest::Method::DELETE,
386 url
387 );
388
389
390
391 request = request.json(&delete_issue_assignees_form);
392
393 let response = request.send().await?;
394
395 if response.status().is_success() {
396 let json: Value = response.json().await?;
397 Ok(json)
398 } else {
399 Err(ApiError::HttpError(response.status().as_u16()))
400 }
401 }
402
403 pub async fn patch_repo_issues_number_assignees(
405 &self,
406 repo: String,
407 number: String,
408 patch_issue_assignees_form: serde_json::Value,
409 ) -> Result<Value> {
410 let path = format!("/{}/-/issues/{}/assignees", repo, number);
411 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
412
413
414
415 let mut request = self.client.request(
416 reqwest::Method::PATCH,
417 url
418 );
419
420
421
422 request = request.json(&patch_issue_assignees_form);
423
424 let response = request.send().await?;
425
426 if response.status().is_success() {
427 let json: Value = response.json().await?;
428 Ok(json)
429 } else {
430 Err(ApiError::HttpError(response.status().as_u16()))
431 }
432 }
433
434 pub async fn get_repo_issues_number_comments(
436 &self,
437 repo: String,
438 number: i64,
439 page: Option<i64>,
440 page_size: Option<i64>,
441 ) -> Result<Value> {
442 let path = format!("/{}/-/issues/{}/comments", repo, number);
443 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
444
445 if let Some(value) = page {
446 url.query_pairs_mut().append_pair("page", &value.to_string());
447 }
448 if let Some(value) = page_size {
449 url.query_pairs_mut().append_pair("page_size", &value.to_string());
450 }
451
452 let request = self.client.request(
453 reqwest::Method::GET,
454 url
455 );
456
457
458
459
460 let response = request.send().await?;
461
462 if response.status().is_success() {
463 let json: Value = response.json().await?;
464 Ok(json)
465 } else {
466 Err(ApiError::HttpError(response.status().as_u16()))
467 }
468 }
469
470 pub async fn post_repo_issues_number_comments(
472 &self,
473 repo: String,
474 number: i64,
475 post_issue_comment_form: serde_json::Value,
476 ) -> Result<Value> {
477 let path = format!("/{}/-/issues/{}/comments", repo, number);
478 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
479
480
481
482 let mut request = self.client.request(
483 reqwest::Method::POST,
484 url
485 );
486
487
488
489 request = request.json(&post_issue_comment_form);
490
491 let response = request.send().await?;
492
493 if response.status().is_success() {
494 let json: Value = response.json().await?;
495 Ok(json)
496 } else {
497 Err(ApiError::HttpError(response.status().as_u16()))
498 }
499 }
500
501 pub async fn get_repo_issues_number_labels(
503 &self,
504 repo: String,
505 number: i64,
506 page: Option<i64>,
507 page_size: Option<i64>,
508 ) -> Result<Value> {
509 let path = format!("/{}/-/issues/{}/labels", repo, number);
510 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
511
512 if let Some(value) = page {
513 url.query_pairs_mut().append_pair("page", &value.to_string());
514 }
515 if let Some(value) = page_size {
516 url.query_pairs_mut().append_pair("page_size", &value.to_string());
517 }
518
519 let request = self.client.request(
520 reqwest::Method::GET,
521 url
522 );
523
524
525
526
527 let response = request.send().await?;
528
529 if response.status().is_success() {
530 let json: Value = response.json().await?;
531 Ok(json)
532 } else {
533 Err(ApiError::HttpError(response.status().as_u16()))
534 }
535 }
536
537 pub async fn post_repo_issues_number_labels(
539 &self,
540 repo: String,
541 number: i64,
542 post_issue_labels_form: serde_json::Value,
543 ) -> Result<Value> {
544 let path = format!("/{}/-/issues/{}/labels", repo, number);
545 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
546
547
548
549 let mut request = self.client.request(
550 reqwest::Method::POST,
551 url
552 );
553
554
555
556 request = request.json(&post_issue_labels_form);
557
558 let response = request.send().await?;
559
560 if response.status().is_success() {
561 let json: Value = response.json().await?;
562 Ok(json)
563 } else {
564 Err(ApiError::HttpError(response.status().as_u16()))
565 }
566 }
567
568 pub async fn put_repo_issues_number_labels(
570 &self,
571 repo: String,
572 number: i64,
573 put_issue_labels_form: serde_json::Value,
574 ) -> Result<Value> {
575 let path = format!("/{}/-/issues/{}/labels", repo, number);
576 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
577
578
579
580 let mut request = self.client.request(
581 reqwest::Method::PUT,
582 url
583 );
584
585
586
587 request = request.json(&put_issue_labels_form);
588
589 let response = request.send().await?;
590
591 if response.status().is_success() {
592 let json: Value = response.json().await?;
593 Ok(json)
594 } else {
595 Err(ApiError::HttpError(response.status().as_u16()))
596 }
597 }
598
599 pub async fn delete_repo_issues_number_labels(
601 &self,
602 repo: String,
603 number: i64,
604 ) -> Result<Value> {
605 let path = format!("/{}/-/issues/{}/labels", repo, number);
606 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
607
608
609 let request = self.client.request(
610 reqwest::Method::DELETE,
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}