1use crate::error::{ApiError, Result};
4use reqwest::Client;
5use serde_json::Value;
6use url::Url;
7
8pub struct GitClient {
10 base_url: String,
11 client: Client,
12}
13
14impl GitClient {
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_git_commits_ref(
28 &self,
29 repo: String,
30 r#ref: String,
31 ) -> Result<Value> {
32 let path = format!("/{}/-/git/commits/{}", repo, r#ref);
33 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
34
35
36 let request = self.client.request(
37 reqwest::Method::GET,
38 url
39 );
40
41
42
43
44 let response = request.send().await?;
45
46 if response.status().is_success() {
47 let json: Value = response.json().await?;
48 Ok(json)
49 } else {
50 Err(ApiError::HttpError(response.status().as_u16()))
51 }
52 }
53
54 pub async fn get_repo_git_commit_statuses_commitish(
56 &self,
57 repo: String,
58 commitish: String,
59 ) -> Result<Value> {
60 let path = format!("/{}/-/git/commit-statuses/{}", repo, commitish);
61 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
62
63
64 let request = self.client.request(
65 reqwest::Method::GET,
66 url
67 );
68
69
70
71
72 let response = request.send().await?;
73
74 if response.status().is_success() {
75 let json: Value = response.json().await?;
76 Ok(json)
77 } else {
78 Err(ApiError::HttpError(response.status().as_u16()))
79 }
80 }
81
82 pub async fn get_repo_git_commit_assets_sha_1(
84 &self,
85 repo: String,
86 sha_1: String,
87 ) -> Result<Value> {
88 let path = format!("/{}/-/git/commit-assets/{}", repo, sha_1);
89 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
90
91
92 let request = self.client.request(
93 reqwest::Method::GET,
94 url
95 );
96
97
98
99
100 let response = request.send().await?;
101
102 if response.status().is_success() {
103 let json: Value = response.json().await?;
104 Ok(json)
105 } else {
106 Err(ApiError::HttpError(response.status().as_u16()))
107 }
108 }
109
110 pub async fn get_repo_git_archive_compare_changed_files_base_head(
112 &self,
113 repo: String,
114 base_head: String,
115 ) -> Result<Value> {
116 let path = format!("/{}/-/git/archive-compare-changed-files/{}", repo, base_head);
117 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
118
119
120 let request = self.client.request(
121 reqwest::Method::GET,
122 url
123 );
124
125
126
127
128 let response = request.send().await?;
129
130 if response.status().is_success() {
131 let json: Value = response.json().await?;
132 Ok(json)
133 } else {
134 Err(ApiError::HttpError(response.status().as_u16()))
135 }
136 }
137
138 pub async fn get_repo_git_head(
140 &self,
141 repo: String,
142 ) -> Result<Value> {
143 let path = format!("/{}/-/git/head", repo);
144 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
145
146
147 let request = self.client.request(
148 reqwest::Method::GET,
149 url
150 );
151
152
153
154
155 let response = request.send().await?;
156
157 if response.status().is_success() {
158 let json: Value = response.json().await?;
159 Ok(json)
160 } else {
161 Err(ApiError::HttpError(response.status().as_u16()))
162 }
163 }
164
165 pub async fn get_repo_git_tag_annotations_tag(
167 &self,
168 repo: String,
169 tag: String,
170 ) -> Result<Value> {
171 let path = format!("/{}/-/git/tag-annotations/{}", repo, tag);
172 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
173
174
175 let request = self.client.request(
176 reqwest::Method::GET,
177 url
178 );
179
180
181
182
183 let response = request.send().await?;
184
185 if response.status().is_success() {
186 let json: Value = response.json().await?;
187 Ok(json)
188 } else {
189 Err(ApiError::HttpError(response.status().as_u16()))
190 }
191 }
192
193 pub async fn put_repo_git_tag_annotations_tag(
195 &self,
196 repo: String,
197 tag: String,
198 put_tag_annotations_form: serde_json::Value,
199 ) -> Result<Value> {
200 let path = format!("/{}/-/git/tag-annotations/{}", repo, tag);
201 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
202
203
204
205 let mut request = self.client.request(
206 reqwest::Method::PUT,
207 url
208 );
209
210
211
212 request = request.json(&put_tag_annotations_form);
213
214 let response = request.send().await?;
215
216 if response.status().is_success() {
217 let json: Value = response.json().await?;
218 Ok(json)
219 } else {
220 Err(ApiError::HttpError(response.status().as_u16()))
221 }
222 }
223
224 pub async fn get_repo_git_archive_commit_changed_files_sha_1(
226 &self,
227 repo: String,
228 sha_1: String,
229 ) -> Result<Value> {
230 let path = format!("/{}/-/git/archive-commit-changed-files/{}", repo, sha_1);
231 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
232
233
234 let request = self.client.request(
235 reqwest::Method::GET,
236 url
237 );
238
239
240
241
242 let response = request.send().await?;
243
244 if response.status().is_success() {
245 let json: Value = response.json().await?;
246 Ok(json)
247 } else {
248 Err(ApiError::HttpError(response.status().as_u16()))
249 }
250 }
251
252 pub async fn get_repo_git_branches_branch(
254 &self,
255 repo: String,
256 branch: String,
257 ) -> Result<Value> {
258 let path = format!("/{}/-/git/branches/{}", repo, branch);
259 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
260
261
262 let request = self.client.request(
263 reqwest::Method::GET,
264 url
265 );
266
267
268
269
270 let response = request.send().await?;
271
272 if response.status().is_success() {
273 let json: Value = response.json().await?;
274 Ok(json)
275 } else {
276 Err(ApiError::HttpError(response.status().as_u16()))
277 }
278 }
279
280 pub async fn delete_repo_git_branches_branch(
282 &self,
283 repo: String,
284 branch: String,
285 ) -> Result<Value> {
286 let path = format!("/{}/-/git/branches/{}", repo, branch);
287 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
288
289
290 let request = self.client.request(
291 reqwest::Method::DELETE,
292 url
293 );
294
295
296
297
298 let response = request.send().await?;
299
300 if response.status().is_success() {
301 let json: Value = response.json().await?;
302 Ok(json)
303 } else {
304 Err(ApiError::HttpError(response.status().as_u16()))
305 }
306 }
307
308 pub async fn post_repo_git_commit_annotations_in_batch(
310 &self,
311 repo: String,
312 get_commit_annotations_form: serde_json::Value,
313 ) -> Result<Value> {
314 let path = format!("/{}/-/git/commit-annotations-in-batch", repo);
315 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
316
317
318
319 let mut request = self.client.request(
320 reqwest::Method::POST,
321 url
322 );
323
324
325
326 request = request.json(&get_commit_annotations_form);
327
328 let response = request.send().await?;
329
330 if response.status().is_success() {
331 let json: Value = response.json().await?;
332 Ok(json)
333 } else {
334 Err(ApiError::HttpError(response.status().as_u16()))
335 }
336 }
337
338 pub async fn get_repo_git_tags(
340 &self,
341 repo: String,
342 page: Option<i64>,
343 page_size: Option<i64>,
344 ) -> Result<Value> {
345 let path = format!("/{}/-/git/tags", repo);
346 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
347
348 if let Some(value) = page {
349 url.query_pairs_mut().append_pair("page", &value.to_string());
350 }
351 if let Some(value) = page_size {
352 url.query_pairs_mut().append_pair("page_size", &value.to_string());
353 }
354
355 let request = self.client.request(
356 reqwest::Method::GET,
357 url
358 );
359
360
361
362
363 let response = request.send().await?;
364
365 if response.status().is_success() {
366 let json: Value = response.json().await?;
367 Ok(json)
368 } else {
369 Err(ApiError::HttpError(response.status().as_u16()))
370 }
371 }
372
373 pub async fn post_repo_git_tags(
375 &self,
376 repo: String,
377 post_tag_form: serde_json::Value,
378 ) -> Result<Value> {
379 let path = format!("/{}/-/git/tags", repo);
380 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
381
382
383
384 let mut request = self.client.request(
385 reqwest::Method::POST,
386 url
387 );
388
389
390
391 request = request.json(&post_tag_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 get_repo_git_commit_annotations_sha(
405 &self,
406 repo: String,
407 sha: String,
408 ) -> Result<Value> {
409 let path = format!("/{}/-/git/commit-annotations/{}", repo, sha);
410 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
411
412
413 let request = self.client.request(
414 reqwest::Method::GET,
415 url
416 );
417
418
419
420
421 let response = request.send().await?;
422
423 if response.status().is_success() {
424 let json: Value = response.json().await?;
425 Ok(json)
426 } else {
427 Err(ApiError::HttpError(response.status().as_u16()))
428 }
429 }
430
431 pub async fn put_repo_git_commit_annotations_sha(
433 &self,
434 repo: String,
435 sha: String,
436 put_commit_annotations_form: serde_json::Value,
437 ) -> Result<Value> {
438 let path = format!("/{}/-/git/commit-annotations/{}", repo, sha);
439 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
440
441
442
443 let mut request = self.client.request(
444 reqwest::Method::PUT,
445 url
446 );
447
448
449
450 request = request.json(&put_commit_annotations_form);
451
452 let response = request.send().await?;
453
454 if response.status().is_success() {
455 let json: Value = response.json().await?;
456 Ok(json)
457 } else {
458 Err(ApiError::HttpError(response.status().as_u16()))
459 }
460 }
461
462 pub async fn post_repo_git_blobs(
464 &self,
465 repo: String,
466 post_blob_form: serde_json::Value,
467 ) -> Result<Value> {
468 let path = format!("/{}/-/git/blobs", repo);
469 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
470
471
472
473 let mut request = self.client.request(
474 reqwest::Method::POST,
475 url
476 );
477
478
479
480 request = request.json(&post_blob_form);
481
482 let response = request.send().await?;
483
484 if response.status().is_success() {
485 let json: Value = response.json().await?;
486 Ok(json)
487 } else {
488 Err(ApiError::HttpError(response.status().as_u16()))
489 }
490 }
491
492 pub async fn get_repo_git_commits(
494 &self,
495 repo: String,
496 sha: Option<String>,
497 author: Option<String>,
498 committer: Option<String>,
499 since: Option<String>,
500 until: Option<String>,
501 page: Option<i64>,
502 page_size: Option<i64>,
503 ) -> Result<Value> {
504 let path = format!("/{}/-/git/commits", repo);
505 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
506
507 if let Some(value) = sha {
508 url.query_pairs_mut().append_pair("sha", &value.to_string());
509 }
510 if let Some(value) = author {
511 url.query_pairs_mut().append_pair("author", &value.to_string());
512 }
513 if let Some(value) = committer {
514 url.query_pairs_mut().append_pair("committer", &value.to_string());
515 }
516 if let Some(value) = since {
517 url.query_pairs_mut().append_pair("since", &value.to_string());
518 }
519 if let Some(value) = until {
520 url.query_pairs_mut().append_pair("until", &value.to_string());
521 }
522 if let Some(value) = page {
523 url.query_pairs_mut().append_pair("page", &value.to_string());
524 }
525 if let Some(value) = page_size {
526 url.query_pairs_mut().append_pair("page_size", &value.to_string());
527 }
528
529 let request = self.client.request(
530 reqwest::Method::GET,
531 url
532 );
533
534
535
536
537 let response = request.send().await?;
538
539 if response.status().is_success() {
540 let json: Value = response.json().await?;
541 Ok(json)
542 } else {
543 Err(ApiError::HttpError(response.status().as_u16()))
544 }
545 }
546
547 pub async fn post_repo_git_commit_assets_sha_1_asset_upload_url(
549 &self,
550 repo: String,
551 sha_1: String,
552 create_commit_asset_upload_url_form: serde_json::Value,
553 ) -> Result<Value> {
554 let path = format!("/{}/-/git/commit-assets/{}/asset-upload-url", repo, sha_1);
555 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
556
557
558
559 let mut request = self.client.request(
560 reqwest::Method::POST,
561 url
562 );
563
564
565
566 request = request.json(&create_commit_asset_upload_url_form);
567
568 let response = request.send().await?;
569
570 if response.status().is_success() {
571 let json: Value = response.json().await?;
572 Ok(json)
573 } else {
574 Err(ApiError::HttpError(response.status().as_u16()))
575 }
576 }
577
578 pub async fn delete_repo_git_commit_assets_sha_1_asset_id(
580 &self,
581 repo: String,
582 sha_1: String,
583 asset_id: String,
584 ) -> Result<Value> {
585 let path = format!("/{}/-/git/commit-assets/{}/{}", repo, sha_1, asset_id);
586 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
587
588
589 let request = self.client.request(
590 reqwest::Method::DELETE,
591 url
592 );
593
594
595
596
597 let response = request.send().await?;
598
599 if response.status().is_success() {
600 let json: Value = response.json().await?;
601 Ok(json)
602 } else {
603 Err(ApiError::HttpError(response.status().as_u16()))
604 }
605 }
606
607 pub async fn delete_repo_git_commit_annotations_sha_key(
609 &self,
610 repo: String,
611 sha: String,
612 key: String,
613 ) -> Result<Value> {
614 let path = format!("/{}/-/git/commit-annotations/{}/{}", repo, sha, key);
615 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
616
617
618 let request = self.client.request(
619 reqwest::Method::DELETE,
620 url
621 );
622
623
624
625
626 let response = request.send().await?;
627
628 if response.status().is_success() {
629 let json: Value = response.json().await?;
630 Ok(json)
631 } else {
632 Err(ApiError::HttpError(response.status().as_u16()))
633 }
634 }
635
636 pub async fn get_repo_git_compare_base_head(
638 &self,
639 repo: String,
640 base_head: String,
641 ) -> Result<Value> {
642 let path = format!("/{}/-/git/compare/{}", repo, base_head);
643 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
644
645
646 let request = self.client.request(
647 reqwest::Method::GET,
648 url
649 );
650
651
652
653
654 let response = request.send().await?;
655
656 if response.status().is_success() {
657 let json: Value = response.json().await?;
658 Ok(json)
659 } else {
660 Err(ApiError::HttpError(response.status().as_u16()))
661 }
662 }
663
664 pub async fn post_repo_git_commit_assets_sha_1_asset_upload_confirmation_upload_token_asset_path(
666 &self,
667 repo: String,
668 sha_1: String,
669 upload_token: String,
670 asset_path: String,
671 ) -> Result<Value> {
672 let path = format!("/{}/-/git/commit-assets/{}/asset-upload-confirmation/{}/{}", repo, sha_1, upload_token, asset_path);
673 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
674
675
676 let request = self.client.request(
677 reqwest::Method::POST,
678 url
679 );
680
681
682
683
684 let response = request.send().await?;
685
686 if response.status().is_success() {
687 let json: Value = response.json().await?;
688 Ok(json)
689 } else {
690 Err(ApiError::HttpError(response.status().as_u16()))
691 }
692 }
693
694 pub async fn get_repo_git_branches(
696 &self,
697 repo: String,
698 page: Option<i64>,
699 page_size: Option<i64>,
700 ) -> Result<Value> {
701 let path = format!("/{}/-/git/branches", repo);
702 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
703
704 if let Some(value) = page {
705 url.query_pairs_mut().append_pair("page", &value.to_string());
706 }
707 if let Some(value) = page_size {
708 url.query_pairs_mut().append_pair("page_size", &value.to_string());
709 }
710
711 let request = self.client.request(
712 reqwest::Method::GET,
713 url
714 );
715
716
717
718
719 let response = request.send().await?;
720
721 if response.status().is_success() {
722 let json: Value = response.json().await?;
723 Ok(json)
724 } else {
725 Err(ApiError::HttpError(response.status().as_u16()))
726 }
727 }
728
729 pub async fn post_repo_git_branches(
731 &self,
732 repo: String,
733 create_branch_form: serde_json::Value,
734 ) -> Result<Value> {
735 let path = format!("/{}/-/git/branches", repo);
736 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
737
738
739
740 let mut request = self.client.request(
741 reqwest::Method::POST,
742 url
743 );
744
745
746
747 request = request.json(&create_branch_form);
748
749 let response = request.send().await?;
750
751 if response.status().is_success() {
752 let json: Value = response.json().await?;
753 Ok(json)
754 } else {
755 Err(ApiError::HttpError(response.status().as_u16()))
756 }
757 }
758
759 pub async fn get_repo_git_contents_file_path(
761 &self,
762 repo: String,
763 file_path: String,
764 r#ref: Option<String>,
765 ) -> Result<Value> {
766 let path = format!("/{}/-/git/contents/{}", repo, file_path);
767 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
768
769 if let Some(value) = r#ref {
770 url.query_pairs_mut().append_pair("ref", &value.to_string());
771 }
772
773 let request = self.client.request(
774 reqwest::Method::GET,
775 url
776 );
777
778
779
780
781 let response = request.send().await?;
782
783 if response.status().is_success() {
784 let json: Value = response.json().await?;
785 Ok(json)
786 } else {
787 Err(ApiError::HttpError(response.status().as_u16()))
788 }
789 }
790
791 pub async fn get_repo_git_tags_tag(
793 &self,
794 repo: String,
795 tag: String,
796 ) -> Result<Value> {
797 let path = format!("/{}/-/git/tags/{}", repo, tag);
798 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
799
800
801 let request = self.client.request(
802 reqwest::Method::GET,
803 url
804 );
805
806
807
808
809 let response = request.send().await?;
810
811 if response.status().is_success() {
812 let json: Value = response.json().await?;
813 Ok(json)
814 } else {
815 Err(ApiError::HttpError(response.status().as_u16()))
816 }
817 }
818
819 pub async fn delete_repo_git_tags_tag(
821 &self,
822 repo: String,
823 tag: String,
824 ) -> Result<Value> {
825 let path = format!("/{}/-/git/tags/{}", repo, tag);
826 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
827
828
829 let request = self.client.request(
830 reqwest::Method::DELETE,
831 url
832 );
833
834
835
836
837 let response = request.send().await?;
838
839 if response.status().is_success() {
840 let json: Value = response.json().await?;
841 Ok(json)
842 } else {
843 Err(ApiError::HttpError(response.status().as_u16()))
844 }
845 }
846
847 pub async fn delete_repo_git_tag_annotations_tag_with_key(
849 &self,
850 repo: String,
851 tag_with_key: String,
852 ) -> Result<Value> {
853 let path = format!("/{}/-/git/tag-annotations/{}", repo, tag_with_key);
854 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
855
856
857 let request = self.client.request(
858 reqwest::Method::DELETE,
859 url
860 );
861
862
863
864
865 let response = request.send().await?;
866
867 if response.status().is_success() {
868 let json: Value = response.json().await?;
869 Ok(json)
870 } else {
871 Err(ApiError::HttpError(response.status().as_u16()))
872 }
873 }
874
875}