azure_rust/
repository.rs

1use crate::{AzureClient, Future};
2
3use crate::pull_requests::{PullRequest, PullRequests};
4pub use repository_create_options::RepoOptions;
5pub use repository_create_response::RepoCreateReponse;
6pub use repository_list_options::RepoListOptions;
7pub use repository_list_response::ReposResponse;
8pub use repository_response::RepoResponse;
9
10pub struct Repository {
11    ops: AzureClient,
12    project: String,
13    repo: String,
14}
15
16impl Repository {
17    #[doc(hidden)]
18    pub fn new<P, R>(ops: AzureClient, project: P, repo: R) -> Self
19    where
20        P: Into<String>,
21        R: Into<String>,
22    {
23        Repository {
24            ops,
25            project: project.into(),
26            repo: repo.into(),
27        }
28    }
29
30    /// DELETE https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}?api-version=5.1
31    pub fn delete(&self) -> Future<()> {
32        self.ops.delete(&self.path(""))
33    }
34
35    /// Get pull requests ref
36    pub fn pulls(&self) -> PullRequests {
37        PullRequests::new(self.ops.clone(), self.project.as_str(), self.repo.as_str())
38    }
39
40    /// Short hand to get a specific pr directly
41    pub fn pull(&self, id: u64) -> PullRequest {
42        PullRequest::new(
43            self.ops.clone(),
44            self.project.as_str(),
45            self.repo.as_str(),
46            id,
47        )
48    }
49
50    fn path(&self, more: &str) -> String {
51        format!(
52            "/{}/{}/_apis/git/repositories/{}{}",
53            self.ops.org, self.project, self.repo, more
54        )
55    }
56
57    /// GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}?api-version=5.1
58    pub fn get(&self) -> Future<RepoResponse> {
59        self.ops.get(&self.path(""))
60    }
61}
62
63mod repository_response {
64    use serde::*;
65    #[derive(Debug, Deserialize)]
66    pub struct RepoResponse {
67        pub id: String,
68        pub name: String,
69        pub url: String,
70        pub project: Project,
71        #[serde(rename = "defaultBranch")]
72        pub default_branch: String,
73        pub size: i64,
74        #[serde(rename = "remoteUrl")]
75        pub remote_url: String,
76        #[serde(rename = "sshUrl")]
77        pub ssh_url: String,
78        #[serde(rename = "webUrl")]
79        pub web_url: String,
80        #[serde(rename = "_links")]
81        pub links: Links,
82    }
83    #[derive(Debug, Deserialize)]
84    pub struct Project {
85        pub id: String,
86        pub name: String,
87        pub url: String,
88        pub state: String,
89        pub revision: i64,
90        pub visibility: String,
91        #[serde(rename = "lastUpdateTime")]
92        pub last_update_time: String,
93    }
94    #[derive(Debug, Deserialize)]
95    pub struct Links {
96        #[serde(rename = "self")]
97        pub self_field: Href,
98        pub project: ProjectHref,
99        pub web: Web,
100        pub ssh: Ssh,
101        pub commits: Commits,
102        pub refs: Refs,
103        #[serde(rename = "pullRequests")]
104        pub pull_requests: PullRequests,
105        pub items: Items,
106        pub pushes: Pushes,
107    }
108    #[derive(Debug, Deserialize)]
109    pub struct Href {
110        pub href: String,
111    }
112    #[derive(Debug, Deserialize)]
113    pub struct ProjectHref {
114        pub href: String,
115    }
116    #[derive(Debug, Deserialize)]
117    pub struct Web {
118        pub href: String,
119    }
120    #[derive(Debug, Deserialize)]
121    pub struct Ssh {
122        pub href: String,
123    }
124    #[derive(Debug, Deserialize)]
125    pub struct Commits {
126        pub href: String,
127    }
128    #[derive(Debug, Deserialize)]
129    pub struct Refs {
130        pub href: String,
131    }
132    #[derive(Debug, Deserialize)]
133    pub struct PullRequests {
134        pub href: String,
135    }
136    #[derive(Debug, Deserialize)]
137    pub struct Items {
138        pub href: String,
139    }
140    #[derive(Debug, Deserialize)]
141    pub struct Pushes {
142        pub href: String,
143    }
144}
145
146pub struct Repositories {
147    ops: AzureClient,
148    project: String,
149}
150
151impl Repositories {
152    pub fn new<P>(ops: AzureClient, project: P) -> Self
153    where
154        P: Into<String>,
155    {
156        Self {
157            ops: ops,
158            project: project.into(),
159        }
160    }
161
162    /// Create a new repository
163    pub fn create(&self, repo: &RepoOptions) -> Future<RepoCreateReponse> {
164        self.ops.post(&self.path(""), json!(repo))
165    }
166
167    fn path(&self, more: &str) -> String {
168        format!(
169            "/{}/{}/_apis/git/repositories{}",
170            self.ops.org, self.project, more
171        )
172    }
173
174    /// list the authenticated users repositories
175    ///
176    /// https://docs.microsoft.com/en-us/rest/api/azure/devops/git/repositories/list?view=azure-devops-rest-5.1
177    pub fn list(&self, options: &RepoListOptions) -> Future<ReposResponse> {
178        let mut uri = vec![self.path("")];
179        if let Some(query) = options.serialize() {
180            uri.push(query);
181        }
182        self.ops.get(&uri.join("?"))
183    }
184}
185
186mod repository_create_options {
187    use serde::*;
188    #[derive(Debug, Default, Serialize)]
189    pub struct RepoOptions {
190        pub name: String,
191    }
192
193    pub struct RepoOptionsBuilder(RepoOptions);
194
195    impl RepoOptionsBuilder {
196        pub(crate) fn new<N>(name: N) -> Self
197        where
198            N: Into<String>,
199        {
200            RepoOptionsBuilder(RepoOptions {
201                name: name.into(),
202                ..Default::default()
203            })
204        }
205        pub fn build(&self) -> RepoOptions {
206            RepoOptions::new(self.0.name.as_str() /*,self.0.project.id.clone()*/)
207        }
208    }
209
210    impl RepoOptions {
211        #[allow(clippy::too_many_arguments)] // exempted
212        pub fn new<N>(name: N) -> Self
213        where
214            N: Into<String>,
215        {
216            RepoOptions { name: name.into() }
217        }
218
219        pub fn builder<N: Into<String>>(name: N) -> RepoOptionsBuilder {
220            RepoOptionsBuilder::new(name)
221        }
222    }
223}
224
225mod repository_create_response {
226    use serde::*;
227    #[derive(Debug, Deserialize)]
228    pub struct RepoCreateReponse {
229        pub id: String,
230        pub name: String,
231        pub url: String,
232        pub project: Project,
233        pub size: i64,
234        #[serde(rename = "remoteUrl")]
235        pub remote_url: String,
236        #[serde(rename = "sshUrl")]
237        pub ssh_url: String,
238        #[serde(rename = "webUrl")]
239        pub web_url: String,
240    }
241
242    #[derive(Debug, Deserialize)]
243    pub struct Project {
244        pub id: String,
245        pub name: String,
246        pub url: String,
247        pub state: String,
248        pub revision: i64,
249        pub visibility: String,
250        #[serde(rename = "lastUpdateTime")]
251        pub last_update_time: String,
252    }
253}
254
255mod repository_list_options {
256    use std::collections::HashMap;
257    use url::form_urlencoded;
258
259    #[derive(Default)]
260    pub struct RepoListOptions {
261        params: HashMap<&'static str, String>,
262    }
263
264    impl RepoListOptions {
265        pub fn builder() -> RepoListOptionsBuilder {
266            RepoListOptionsBuilder::default()
267        }
268
269        /// serialize options as a string. returns None if no options are defined
270        pub fn serialize(&self) -> Option<String> {
271            if self.params.is_empty() {
272                None
273            } else {
274                let encoded: String = form_urlencoded::Serializer::new(String::new())
275                    .extend_pairs(&self.params)
276                    .finish();
277                Some(encoded)
278            }
279        }
280    }
281
282    #[derive(Default)]
283    pub struct RepoListOptionsBuilder(RepoListOptions);
284
285    impl RepoListOptionsBuilder {
286        pub fn include_hidden(&mut self, include_hidden: bool) -> &mut Self {
287            self.0
288                .params
289                .insert("includeHidden", include_hidden.to_string());
290            self
291        }
292
293        pub fn include_links(&mut self, include_links: bool) -> &mut Self {
294            self.0
295                .params
296                .insert("includeLinks", include_links.to_string());
297            self
298        }
299
300        pub fn include_all_urls(&mut self, include_all_urls: bool) -> &mut Self {
301            self.0
302                .params
303                .insert("includeAllUrls", include_all_urls.to_string());
304            self
305        }
306
307        pub fn build(&self) -> RepoListOptions {
308            RepoListOptions {
309                params: self.0.params.clone(),
310            }
311        }
312    }
313}
314
315mod repository_list_response {
316    use serde::*;
317    #[derive(Debug, Deserialize)]
318    pub struct ReposResponse {
319        pub value: Vec<Value>,
320        pub count: i64,
321    }
322    #[derive(Debug, Deserialize)]
323    pub struct Value {
324        pub id: String,
325        pub name: String,
326        pub url: String,
327        pub project: Project,
328        #[serde(rename = "defaultBranch")]
329        pub default_branch: Option<String>,
330        pub size: i64,
331        #[serde(rename = "remoteUrl")]
332        pub remote_url: String,
333        #[serde(rename = "sshUrl")]
334        pub ssh_url: String,
335        #[serde(rename = "webUrl")]
336        pub web_url: String,
337    }
338
339    #[derive(Debug, Deserialize)]
340    pub struct Project {
341        pub id: String,
342        pub name: String,
343        pub url: String,
344        pub state: String,
345        pub revision: i64,
346        pub visibility: String,
347        #[serde(rename = "lastUpdateTime")]
348        pub last_update_time: String,
349        pub description: Option<String>,
350    }
351}