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_branches_branch(
28 &self,
29 repo: String,
30 branch: String,
31 ) -> Result<Value> {
32 let path = format!("/{}/-/git/branches/{}", repo, branch);
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 delete_repo_git_branches_branch(
56 &self,
57 repo: String,
58 branch: String,
59 ) -> Result<Value> {
60 let path = format!("/{}/-/git/branches/{}", repo, branch);
61 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
62
63
64 let request = self.client.request(
65 reqwest::Method::DELETE,
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_annotations_sha(
84 &self,
85 repo: String,
86 sha: String,
87 ) -> Result<Value> {
88 let path = format!("/{}/-/git/commit-annotations/{}", repo, sha);
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 put_repo_git_commit_annotations_sha(
112 &self,
113 repo: String,
114 sha: String,
115 put_commit_annotations_form: serde_json::Value,
116 ) -> Result<Value> {
117 let path = format!("/{}/-/git/commit-annotations/{}", repo, sha);
118 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
119
120
121
122 let mut request = self.client.request(
123 reqwest::Method::PUT,
124 url
125 );
126
127
128
129 request = request.json(&put_commit_annotations_form);
130
131 let response = request.send().await?;
132
133 if response.status().is_success() {
134 let json: Value = response.json().await?;
135 Ok(json)
136 } else {
137 Err(ApiError::HttpError(response.status().as_u16()))
138 }
139 }
140
141 pub async fn get_repo_git_branches(
143 &self,
144 repo: String,
145 page: Option<i64>,
146 page_size: Option<i64>,
147 ) -> Result<Value> {
148 let path = format!("/{}/-/git/branches", repo);
149 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
150
151 if let Some(value) = page {
152 url.query_pairs_mut().append_pair("page", &value.to_string());
153 }
154 if let Some(value) = page_size {
155 url.query_pairs_mut().append_pair("page_size", &value.to_string());
156 }
157
158 let request = self.client.request(
159 reqwest::Method::GET,
160 url
161 );
162
163
164
165
166 let response = request.send().await?;
167
168 if response.status().is_success() {
169 let json: Value = response.json().await?;
170 Ok(json)
171 } else {
172 Err(ApiError::HttpError(response.status().as_u16()))
173 }
174 }
175
176 pub async fn post_repo_git_branches(
178 &self,
179 repo: String,
180 create_branch_form: serde_json::Value,
181 ) -> Result<Value> {
182 let path = format!("/{}/-/git/branches", repo);
183 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
184
185
186
187 let mut request = self.client.request(
188 reqwest::Method::POST,
189 url
190 );
191
192
193
194 request = request.json(&create_branch_form);
195
196 let response = request.send().await?;
197
198 if response.status().is_success() {
199 let json: Value = response.json().await?;
200 Ok(json)
201 } else {
202 Err(ApiError::HttpError(response.status().as_u16()))
203 }
204 }
205
206 pub async fn get_repo_git_commits(
208 &self,
209 repo: String,
210 sha: Option<String>,
211 author: Option<String>,
212 committer: Option<String>,
213 since: Option<String>,
214 until: Option<String>,
215 page: Option<i64>,
216 page_size: Option<i64>,
217 ) -> Result<Value> {
218 let path = format!("/{}/-/git/commits", repo);
219 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
220
221 if let Some(value) = sha {
222 url.query_pairs_mut().append_pair("sha", &value.to_string());
223 }
224 if let Some(value) = author {
225 url.query_pairs_mut().append_pair("author", &value.to_string());
226 }
227 if let Some(value) = committer {
228 url.query_pairs_mut().append_pair("committer", &value.to_string());
229 }
230 if let Some(value) = since {
231 url.query_pairs_mut().append_pair("since", &value.to_string());
232 }
233 if let Some(value) = until {
234 url.query_pairs_mut().append_pair("until", &value.to_string());
235 }
236 if let Some(value) = page {
237 url.query_pairs_mut().append_pair("page", &value.to_string());
238 }
239 if let Some(value) = page_size {
240 url.query_pairs_mut().append_pair("page_size", &value.to_string());
241 }
242
243 let request = self.client.request(
244 reqwest::Method::GET,
245 url
246 );
247
248
249
250
251 let response = request.send().await?;
252
253 if response.status().is_success() {
254 let json: Value = response.json().await?;
255 Ok(json)
256 } else {
257 Err(ApiError::HttpError(response.status().as_u16()))
258 }
259 }
260
261 pub async fn get_repo_git_archive_compare_changed_files_base_head(
263 &self,
264 repo: String,
265 base_head: String,
266 ) -> Result<Value> {
267 let path = format!("/{}/-/git/archive-compare-changed-files/{}", repo, base_head);
268 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
269
270
271 let request = self.client.request(
272 reqwest::Method::GET,
273 url
274 );
275
276
277
278
279 let response = request.send().await?;
280
281 if response.status().is_success() {
282 let json: Value = response.json().await?;
283 Ok(json)
284 } else {
285 Err(ApiError::HttpError(response.status().as_u16()))
286 }
287 }
288
289 pub async fn post_repo_git_blobs(
291 &self,
292 repo: String,
293 post_blob_form: serde_json::Value,
294 ) -> Result<Value> {
295 let path = format!("/{}/-/git/blobs", repo);
296 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
297
298
299
300 let mut request = self.client.request(
301 reqwest::Method::POST,
302 url
303 );
304
305
306
307 request = request.json(&post_blob_form);
308
309 let response = request.send().await?;
310
311 if response.status().is_success() {
312 let json: Value = response.json().await?;
313 Ok(json)
314 } else {
315 Err(ApiError::HttpError(response.status().as_u16()))
316 }
317 }
318
319 pub async fn get_repo_git_tag_annotations_tag(
321 &self,
322 repo: String,
323 tag: String,
324 ) -> Result<Value> {
325 let path = format!("/{}/-/git/tag-annotations/{}", repo, tag);
326 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
327
328
329 let request = self.client.request(
330 reqwest::Method::GET,
331 url
332 );
333
334
335
336
337 let response = request.send().await?;
338
339 if response.status().is_success() {
340 let json: Value = response.json().await?;
341 Ok(json)
342 } else {
343 Err(ApiError::HttpError(response.status().as_u16()))
344 }
345 }
346
347 pub async fn put_repo_git_tag_annotations_tag(
349 &self,
350 repo: String,
351 tag: String,
352 put_tag_annotations_form: serde_json::Value,
353 ) -> Result<Value> {
354 let path = format!("/{}/-/git/tag-annotations/{}", repo, tag);
355 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
356
357
358
359 let mut request = self.client.request(
360 reqwest::Method::PUT,
361 url
362 );
363
364
365
366 request = request.json(&put_tag_annotations_form);
367
368 let response = request.send().await?;
369
370 if response.status().is_success() {
371 let json: Value = response.json().await?;
372 Ok(json)
373 } else {
374 Err(ApiError::HttpError(response.status().as_u16()))
375 }
376 }
377
378 pub async fn get_repo_git_commit_statuses_commitish(
380 &self,
381 repo: String,
382 commitish: String,
383 ) -> Result<Value> {
384 let path = format!("/{}/-/git/commit-statuses/{}", repo, commitish);
385 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
386
387
388 let request = self.client.request(
389 reqwest::Method::GET,
390 url
391 );
392
393
394
395
396 let response = request.send().await?;
397
398 if response.status().is_success() {
399 let json: Value = response.json().await?;
400 Ok(json)
401 } else {
402 Err(ApiError::HttpError(response.status().as_u16()))
403 }
404 }
405
406 pub async fn get_repo_git_deferred_commits(
408 &self,
409 repo: String,
410 cs: String,
411 ) -> Result<Value> {
412 let path = format!("/{}/-/git/deferred-commits", repo);
413 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
414
415 url.query_pairs_mut().append_pair("cs", &cs.to_string());
416
417 let request = self.client.request(
418 reqwest::Method::GET,
419 url
420 );
421
422
423
424
425 let response = request.send().await?;
426
427 if response.status().is_success() {
428 let json: Value = response.json().await?;
429 Ok(json)
430 } else {
431 Err(ApiError::HttpError(response.status().as_u16()))
432 }
433 }
434
435 pub async fn delete_repo_git_tag_annotations_tag_with_key(
437 &self,
438 repo: String,
439 tag_with_key: String,
440 ) -> Result<Value> {
441 let path = format!("/{}/-/git/tag-annotations/{}", repo, tag_with_key);
442 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
443
444
445 let request = self.client.request(
446 reqwest::Method::DELETE,
447 url
448 );
449
450
451
452
453 let response = request.send().await?;
454
455 if response.status().is_success() {
456 let json: Value = response.json().await?;
457 Ok(json)
458 } else {
459 Err(ApiError::HttpError(response.status().as_u16()))
460 }
461 }
462
463 pub async fn get_repo_git_commit_assets_sha_1(
465 &self,
466 repo: String,
467 sha_1: String,
468 ) -> Result<Value> {
469 let path = format!("/{}/-/git/commit-assets/{}", repo, sha_1);
470 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
471
472
473 let request = self.client.request(
474 reqwest::Method::GET,
475 url
476 );
477
478
479
480
481 let response = request.send().await?;
482
483 if response.status().is_success() {
484 let json: Value = response.json().await?;
485 Ok(json)
486 } else {
487 Err(ApiError::HttpError(response.status().as_u16()))
488 }
489 }
490
491 pub async fn get_repo_git_tags(
493 &self,
494 repo: String,
495 page: Option<i64>,
496 page_size: Option<i64>,
497 ) -> Result<Value> {
498 let path = format!("/{}/-/git/tags", repo);
499 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
500
501 if let Some(value) = page {
502 url.query_pairs_mut().append_pair("page", &value.to_string());
503 }
504 if let Some(value) = page_size {
505 url.query_pairs_mut().append_pair("page_size", &value.to_string());
506 }
507
508 let request = self.client.request(
509 reqwest::Method::GET,
510 url
511 );
512
513
514
515
516 let response = request.send().await?;
517
518 if response.status().is_success() {
519 let json: Value = response.json().await?;
520 Ok(json)
521 } else {
522 Err(ApiError::HttpError(response.status().as_u16()))
523 }
524 }
525
526 pub async fn post_repo_git_tags(
528 &self,
529 repo: String,
530 post_tag_form: serde_json::Value,
531 ) -> Result<Value> {
532 let path = format!("/{}/-/git/tags", repo);
533 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
534
535
536
537 let mut request = self.client.request(
538 reqwest::Method::POST,
539 url
540 );
541
542
543
544 request = request.json(&post_tag_form);
545
546 let response = request.send().await?;
547
548 if response.status().is_success() {
549 let json: Value = response.json().await?;
550 Ok(json)
551 } else {
552 Err(ApiError::HttpError(response.status().as_u16()))
553 }
554 }
555
556 pub async fn post_repo_git_commit_annotations_in_batch(
558 &self,
559 repo: String,
560 get_commit_annotations_form: serde_json::Value,
561 ) -> Result<Value> {
562 let path = format!("/{}/-/git/commit-annotations-in-batch", repo);
563 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
564
565
566
567 let mut request = self.client.request(
568 reqwest::Method::POST,
569 url
570 );
571
572
573
574 request = request.json(&get_commit_annotations_form);
575
576 let response = request.send().await?;
577
578 if response.status().is_success() {
579 let json: Value = response.json().await?;
580 Ok(json)
581 } else {
582 Err(ApiError::HttpError(response.status().as_u16()))
583 }
584 }
585
586 pub async fn post_repo_git_commit_assets_sha_1_asset_upload_confirmation_upload_token_asset_path(
588 &self,
589 repo: String,
590 sha_1: String,
591 token: String,
592 asset_path: String,
593 ) -> Result<Value> {
594 let path = format!("/{}/-/git/commit-assets/{}/asset-upload-confirmation/{}/{}", repo, sha_1, token, asset_path);
595 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
596
597
598 let request = self.client.request(
599 reqwest::Method::POST,
600 url
601 );
602
603
604
605
606 let response = request.send().await?;
607
608 if response.status().is_success() {
609 let json: Value = response.json().await?;
610 Ok(json)
611 } else {
612 Err(ApiError::HttpError(response.status().as_u16()))
613 }
614 }
615
616 pub async fn get_repo_git_archive_commit_changed_files_sha_1(
618 &self,
619 repo: String,
620 sha_1: String,
621 ) -> Result<Value> {
622 let path = format!("/{}/-/git/archive-commit-changed-files/{}", repo, sha_1);
623 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
624
625
626 let request = self.client.request(
627 reqwest::Method::GET,
628 url
629 );
630
631
632
633
634 let response = request.send().await?;
635
636 if response.status().is_success() {
637 let json: Value = response.json().await?;
638 Ok(json)
639 } else {
640 Err(ApiError::HttpError(response.status().as_u16()))
641 }
642 }
643
644 pub async fn delete_repo_git_commit_annotations_sha_key(
646 &self,
647 repo: String,
648 sha: String,
649 key: String,
650 ) -> Result<Value> {
651 let path = format!("/{}/-/git/commit-annotations/{}/{}", repo, sha, key);
652 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
653
654
655 let request = self.client.request(
656 reqwest::Method::DELETE,
657 url
658 );
659
660
661
662
663 let response = request.send().await?;
664
665 if response.status().is_success() {
666 let json: Value = response.json().await?;
667 Ok(json)
668 } else {
669 Err(ApiError::HttpError(response.status().as_u16()))
670 }
671 }
672
673 pub async fn get_repo_git_tags_tag(
675 &self,
676 repo: String,
677 tag: String,
678 ) -> Result<Value> {
679 let path = format!("/{}/-/git/tags/{}", repo, tag);
680 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
681
682
683 let request = self.client.request(
684 reqwest::Method::GET,
685 url
686 );
687
688
689
690
691 let response = request.send().await?;
692
693 if response.status().is_success() {
694 let json: Value = response.json().await?;
695 Ok(json)
696 } else {
697 Err(ApiError::HttpError(response.status().as_u16()))
698 }
699 }
700
701 pub async fn delete_repo_git_tags_tag(
703 &self,
704 repo: String,
705 tag: String,
706 ) -> Result<Value> {
707 let path = format!("/{}/-/git/tags/{}", repo, tag);
708 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
709
710
711 let request = self.client.request(
712 reqwest::Method::DELETE,
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 delete_repo_git_commit_assets_sha_1_asset_id(
731 &self,
732 repo: String,
733 sha_1: String,
734 asset_id: String,
735 ) -> Result<Value> {
736 let path = format!("/{}/-/git/commit-assets/{}/{}", repo, sha_1, asset_id);
737 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
738
739
740 let request = self.client.request(
741 reqwest::Method::DELETE,
742 url
743 );
744
745
746
747
748 let response = request.send().await?;
749
750 if response.status().is_success() {
751 let json: Value = response.json().await?;
752 Ok(json)
753 } else {
754 Err(ApiError::HttpError(response.status().as_u16()))
755 }
756 }
757
758 pub async fn get_repo_git_contents_file_path(
760 &self,
761 repo: String,
762 file_path: String,
763 r#ref: Option<String>,
764 ) -> Result<Value> {
765 let path = format!("/{}/-/git/contents/{}", repo, file_path);
766 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
767
768 if let Some(value) = r#ref {
769 url.query_pairs_mut().append_pair("ref", &value.to_string());
770 }
771
772 let request = self.client.request(
773 reqwest::Method::GET,
774 url
775 );
776
777
778
779
780 let response = request.send().await?;
781
782 if response.status().is_success() {
783 let json: Value = response.json().await?;
784 Ok(json)
785 } else {
786 Err(ApiError::HttpError(response.status().as_u16()))
787 }
788 }
789
790 pub async fn get_repo_git_head(
792 &self,
793 repo: String,
794 ) -> Result<Value> {
795 let path = format!("/{}/-/git/head", repo);
796 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
797
798
799 let request = self.client.request(
800 reqwest::Method::GET,
801 url
802 );
803
804
805
806
807 let response = request.send().await?;
808
809 if response.status().is_success() {
810 let json: Value = response.json().await?;
811 Ok(json)
812 } else {
813 Err(ApiError::HttpError(response.status().as_u16()))
814 }
815 }
816
817 pub async fn get_repo_git_commits_ref(
819 &self,
820 repo: String,
821 r#ref: String,
822 ) -> Result<Value> {
823 let path = format!("/{}/-/git/commits/{}", repo, r#ref);
824 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
825
826
827 let request = self.client.request(
828 reqwest::Method::GET,
829 url
830 );
831
832
833
834
835 let response = request.send().await?;
836
837 if response.status().is_success() {
838 let json: Value = response.json().await?;
839 Ok(json)
840 } else {
841 Err(ApiError::HttpError(response.status().as_u16()))
842 }
843 }
844
845 pub async fn get_repo_git_compare_base_head(
847 &self,
848 repo: String,
849 base_head: String,
850 ) -> Result<Value> {
851 let path = format!("/{}/-/git/compare/{}", repo, base_head);
852 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
853
854
855 let request = self.client.request(
856 reqwest::Method::GET,
857 url
858 );
859
860
861
862
863 let response = request.send().await?;
864
865 if response.status().is_success() {
866 let json: Value = response.json().await?;
867 Ok(json)
868 } else {
869 Err(ApiError::HttpError(response.status().as_u16()))
870 }
871 }
872
873 pub async fn post_repo_git_commit_assets_sha_1_asset_upload_url(
875 &self,
876 repo: String,
877 sha_1: String,
878 create_commit_asset_upload_url_form: serde_json::Value,
879 ) -> Result<Value> {
880 let path = format!("/{}/-/git/commit-assets/{}/asset-upload-url", repo, sha_1);
881 let url = Url::parse(&format!("{}{}", self.base_url, path))?;
882
883
884
885 let mut request = self.client.request(
886 reqwest::Method::POST,
887 url
888 );
889
890
891
892 request = request.json(&create_commit_asset_upload_url_form);
893
894 let response = request.send().await?;
895
896 if response.status().is_success() {
897 let json: Value = response.json().await?;
898 Ok(json)
899 } else {
900 Err(ApiError::HttpError(response.status().as_u16()))
901 }
902 }
903
904 pub async fn get_repo_lfs_oid(
906 &self,
907 repo: String,
908 oid: String,
909 name: String,
910 ) -> Result<Value> {
911 let path = format!("/{}/-/lfs/{}", repo, oid);
912 let mut url = Url::parse(&format!("{}{}", self.base_url, path))?;
913
914 url.query_pairs_mut().append_pair("name", &name.to_string());
915
916 let request = self.client.request(
917 reqwest::Method::GET,
918 url
919 );
920
921
922
923
924 let response = request.send().await?;
925
926 if response.status().is_success() {
927 let json: Value = response.json().await?;
928 Ok(json)
929 } else {
930 Err(ApiError::HttpError(response.status().as_u16()))
931 }
932 }
933
934}