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 pub fn delete(&self) -> Future<()> {
32 self.ops.delete(&self.path(""))
33 }
34
35 pub fn pulls(&self) -> PullRequests {
37 PullRequests::new(self.ops.clone(), self.project.as_str(), self.repo.as_str())
38 }
39
40 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 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 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 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() )
207 }
208 }
209
210 impl RepoOptions {
211 #[allow(clippy::too_many_arguments)] 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 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}