1use std::collections::HashMap;
3
4use url::form_urlencoded;
5
6use crate::{AzureClient, Future};
7pub use new_project_options::{ProjectsOptions, ProjectsOptionsBuilder};
8pub use new_project_response::ProjectStatus;
9pub use project_list_response::ProjectsResponse;
10pub use project_response::ProjectResponse;
11
12pub struct Projects {
13 ops: AzureClient,
14}
15
16impl Projects {
17 #[doc(hidden)]
18 pub fn new(ops: AzureClient) -> Self {
19 Self { ops }
20 }
21
22 pub fn create(&self, project: &ProjectsOptions) -> Future<ProjectStatus> {
24 self.ops.post(&self.path(""), json!(project))
25 }
26
27 fn path(&self, more: &str) -> String {
28 format!("/{}/{}/_apis/projects", self.ops.org, more)
29 }
30
31 pub fn list(&self, options: &ProjectOptions) -> Future<ProjectsResponse> {
33 let mut uri = vec![self.path("")];
34 if let Some(query) = options.serialize() {
35 uri.push(query);
36 }
37
38 self.ops.get(&uri.join("?"))
40 }
41}
42mod new_project_response {
43 use serde::*;
44 #[derive(Debug, Default, Deserialize)]
45 pub struct ProjectStatus {
46 pub id: String,
47 pub status: String,
48 pub url: String,
49 }
50}
51
52mod new_project_options {
53 use serde::*;
54 #[derive(Debug, Default, Serialize)]
57 pub struct ProjectsOptions {
58 pub name: String,
59 pub description: String,
60 pub capabilities: Capabilities,
61 }
62 #[derive(Debug, Default, Serialize)]
63 pub struct Capabilities {
64 pub versioncontrol: Versioncontrol,
65 #[serde(rename = "processTemplate")]
66 pub process_template: ProcessTemplate,
67 }
68 #[derive(Debug, Default, Serialize)]
69 pub struct Versioncontrol {
70 #[serde(rename = "sourceControlType")]
71 pub source_control_type: String,
72 }
73 #[derive(Debug, Default, Serialize)]
74 pub struct ProcessTemplate {
75 #[serde(rename = "templateTypeId")]
76 pub template_type_id: String,
77 }
78
79 pub struct ProjectsOptionsBuilder(ProjectsOptions);
80
81 impl ProjectsOptionsBuilder {
82 pub(crate) fn new<N>(name: N) -> Self
83 where
84 N: Into<String>,
85 {
86 ProjectsOptionsBuilder(ProjectsOptions {
87 name: name.into(),
88 ..Default::default()
89 })
90 }
91
92 pub fn description<D>(&mut self, description: D) -> &mut Self
93 where
94 D: Into<String>,
95 {
96 self.0.description = description.into();
97 self
98 }
99
100 pub fn source_control_type<H>(&mut self, source_control_type: H) -> &mut Self
101 where
102 H: Into<String>,
103 {
104 self.0.capabilities.versioncontrol.source_control_type = source_control_type.into();
105 self
106 }
107
108 pub fn template_type_id(&mut self, template_type_id: String) -> &mut Self {
109 self.0.capabilities.process_template.template_type_id = template_type_id;
110 self
111 }
112
113 pub fn build(&self) -> ProjectsOptions {
114 ProjectsOptions::new(
115 self.0.name.as_str(),
116 self.0.description.as_str(),
117 self.0
118 .capabilities
119 .versioncontrol
120 .source_control_type
121 .clone(),
122 self.0
123 .capabilities
124 .process_template
125 .template_type_id
126 .clone(),
127 )
128 }
129 }
130
131 impl ProjectsOptions {
132 #[allow(clippy::too_many_arguments)] pub fn new<N, D, H, E>(
134 name: N,
135 description: D,
136 source_control_type: H,
137 template_type_id: E,
138 ) -> Self
139 where
140 N: Into<String>,
141 D: Into<String>,
142 H: Into<String>,
143 E: Into<String>,
144 {
145 ProjectsOptions {
146 name: name.into(),
147 description: description.into(),
148 capabilities: Capabilities {
149 versioncontrol: Versioncontrol {
150 source_control_type: source_control_type.into(),
151 },
152 process_template: ProcessTemplate {
153 template_type_id: template_type_id.into(),
154 },
155 },
156 }
157 }
158
159 pub fn builder<N: Into<String>>(name: N) -> ProjectsOptionsBuilder {
160 ProjectsOptionsBuilder::new(name)
161 }
162 }
163}
164
165mod project_list_response {
166 use serde::Deserialize;
167 #[derive(Debug, Deserialize)]
168 #[serde(rename_all = "camelCase")]
169 pub struct ProjectsResponse {
170 pub value: Vec<Value>,
171 pub count: i64,
172 }
173 #[derive(Debug, Deserialize)]
174 #[serde(rename_all = "camelCase")]
175 pub struct Value {
176 pub id: String,
177 pub name: String,
178 pub url: String,
179 pub state: String,
180 pub revision: i64,
181 pub visibility: String,
182 pub last_update_time: String,
183 }
184}
185
186#[derive(Default)]
187pub struct ProjectOptions {
188 params: HashMap<&'static str, String>,
189}
190
191impl ProjectOptions {
192 pub fn serialize(&self) -> Option<String> {
194 if self.params.is_empty() {
195 None
196 } else {
197 let encoded: String = form_urlencoded::Serializer::new(String::new())
198 .extend_pairs(&self.params)
199 .finish();
200 Some(encoded)
201 }
202 }
203}
204
205pub struct Project {
206 ops: AzureClient,
207 project: String,
208}
209
210impl Project {
211 #[doc(hidden)]
212 pub fn new<P>(ops: AzureClient, project: P) -> Self
213 where
214 P: Into<String>,
215 {
216 Project {
217 ops: ops,
218 project: project.into(),
219 }
220 }
221
222 pub fn get(&self) -> Future<ProjectResponse> {
223 self.ops.get(&self.path(""))
224 }
225
226 pub fn delete(&self) -> Future<ProjectStatus> {
227 self.ops.delete(&self.path(""))
228 }
229
230 fn path(&self, more: &str) -> String {
232 format!("/{}/_apis/projects/{}{}", self.ops.org, self.project, more)
233 }
234}
235
236mod project_response {
237 use serde::Deserialize;
238 #[derive(Debug, Deserialize)]
239 #[serde(rename_all = "camelCase")]
240 pub struct ProjectResponse {
241 pub id: String,
242 pub name: String,
243 pub url: String,
244 pub state: String,
245 pub revision: i64,
246 #[serde(rename = "_links")]
247 pub links: Links,
248 pub visibility: String,
249 #[serde(rename = "defaultTeam")]
250 pub default_team: DefaultTeam,
251 #[serde(rename = "lastUpdateTime")]
252 pub last_update_time: String,
253 }
254
255 #[derive(Debug, Deserialize)]
256 pub struct Links {
257 #[serde(rename = "self")]
258 pub self_field: Href,
259 pub collection: Collection,
260 pub web: Web,
261 }
262
263 #[derive(Debug, Deserialize)]
264 pub struct Href {
265 pub href: String,
266 }
267
268 #[derive(Debug, Deserialize)]
269 pub struct Collection {
270 pub href: String,
271 }
272
273 #[derive(Debug, Deserialize)]
274 pub struct Web {
275 pub href: String,
276 }
277
278 #[derive(Debug, Deserialize)]
279 pub struct DefaultTeam {
280 pub id: String,
281 pub name: String,
282 pub url: String,
283 }
284}