ironflow_ops_gitlab/endpoints/merge_requests.rs
1//! Merge request routes missing from the `gitlab` crate:
2//! `POST /projects/:id/merge_requests/:iid/discussions/:discussion_id/notes`,
3//! `PUT /projects/:id/merge_requests/:iid/discussions/:discussion_id`,
4//! `GET /projects/:id/merge_requests/:iid/versions[/:version_id]` and
5//! `DELETE /projects/:id/merge_requests/:iid/notes/:note_id`.
6
7use std::borrow::Cow;
8
9use gitlab::api::common::NameOrId;
10use gitlab::api::endpoint_prelude::{BodyError, Endpoint, FormParams, Method};
11
12/// Add a note (reply) to an existing merge request discussion.
13///
14/// Maps to `POST /projects/:id/merge_requests/:merge_request/discussions/:discussion_id/notes`.
15///
16/// # Examples
17///
18/// ```no_run
19/// use ironflow_ops_gitlab::GitLab;
20/// use ironflow_ops_gitlab::endpoints::merge_requests::CreateMergeRequestDiscussionNote;
21/// use gitlab::api::common::NameOrId;
22///
23/// # async fn example() -> Result<(), ironflow_core::error::OperationError> {
24/// let gitlab = GitLab::new("glpat-xxxx", "gitlab.com").await?;
25/// let endpoint = CreateMergeRequestDiscussionNote {
26/// project: NameOrId::from(42),
27/// merge_request: 7,
28/// discussion_id: "abcd1234".to_string(),
29/// body: "Looks good, thanks!".to_string(),
30/// };
31/// let op = gitlab.op(endpoint);
32/// # Ok(())
33/// # }
34/// ```
35///
36/// # Errors
37///
38/// Returns an error if the request fails or the response cannot be deserialized (e.g. the
39/// project, merge request or discussion does not exist).
40pub struct CreateMergeRequestDiscussionNote {
41 /// The project the merge request belongs to.
42 pub project: NameOrId<'static>,
43 /// The internal ID (`iid`) of the merge request.
44 pub merge_request: u64,
45 /// The ID of the discussion thread to reply to.
46 pub discussion_id: String,
47 /// The text of the note.
48 pub body: String,
49}
50
51impl Endpoint for CreateMergeRequestDiscussionNote {
52 fn method(&self) -> Method {
53 Method::POST
54 }
55
56 fn endpoint(&self) -> Cow<'static, str> {
57 format!(
58 "projects/{}/merge_requests/{}/discussions/{}/notes",
59 self.project, self.merge_request, self.discussion_id,
60 )
61 .into()
62 }
63
64 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
65 let mut params = FormParams::default();
66 params.push("body", self.body.as_str());
67 params.into_body()
68 }
69}
70
71/// Resolve or unresolve an existing merge request discussion.
72///
73/// Maps to `PUT /projects/:id/merge_requests/:merge_request/discussions/:discussion_id`.
74///
75/// # Examples
76///
77/// ```no_run
78/// use ironflow_ops_gitlab::GitLab;
79/// use ironflow_ops_gitlab::endpoints::merge_requests::ResolveMergeRequestDiscussion;
80/// use gitlab::api::common::NameOrId;
81///
82/// # async fn example() -> Result<(), ironflow_core::error::OperationError> {
83/// let gitlab = GitLab::new("glpat-xxxx", "gitlab.com").await?;
84/// let endpoint = ResolveMergeRequestDiscussion {
85/// project: NameOrId::from(42),
86/// merge_request: 7,
87/// discussion_id: "abcd1234".to_string(),
88/// resolved: true,
89/// };
90/// let op = gitlab.op(endpoint);
91/// # Ok(())
92/// # }
93/// ```
94///
95/// # Errors
96///
97/// Returns an error if the request fails or the response cannot be deserialized (e.g. the
98/// project, merge request or discussion does not exist).
99pub struct ResolveMergeRequestDiscussion {
100 /// The project the merge request belongs to.
101 pub project: NameOrId<'static>,
102 /// The internal ID (`iid`) of the merge request.
103 pub merge_request: u64,
104 /// The ID of the discussion thread to resolve or unresolve.
105 pub discussion_id: String,
106 /// Whether the discussion should be marked resolved.
107 pub resolved: bool,
108}
109
110impl Endpoint for ResolveMergeRequestDiscussion {
111 fn method(&self) -> Method {
112 Method::PUT
113 }
114
115 fn endpoint(&self) -> Cow<'static, str> {
116 format!(
117 "projects/{}/merge_requests/{}/discussions/{}",
118 self.project, self.merge_request, self.discussion_id,
119 )
120 .into()
121 }
122
123 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
124 let mut params = FormParams::default();
125 params.push("resolved", self.resolved);
126 params.into_body()
127 }
128}
129
130/// List the diff versions of a merge request, newest first.
131///
132/// Maps to `GET /projects/:id/merge_requests/:merge_request/versions`. Each
133/// version carries `head_commit_sha`, `base_commit_sha` and `start_commit_sha`:
134/// one version per push, which tells a rebase from a content change.
135///
136/// # Examples
137///
138/// ```no_run
139/// use ironflow_ops_gitlab::GitLab;
140/// use ironflow_ops_gitlab::endpoints::merge_requests::MergeRequestVersions;
141/// use gitlab::api::common::NameOrId;
142///
143/// # async fn example() -> Result<(), ironflow_core::error::OperationError> {
144/// let gitlab = GitLab::new("glpat-xxxx", "gitlab.com").await?;
145/// let endpoint = MergeRequestVersions {
146/// project: NameOrId::from("group/project"),
147/// merge_request: 7,
148/// };
149/// let op = gitlab.op(endpoint);
150/// # Ok(())
151/// # }
152/// ```
153///
154/// # Errors
155///
156/// Returns an error if the request fails (e.g. the project or merge request
157/// does not exist).
158pub struct MergeRequestVersions {
159 /// The project the merge request belongs to.
160 pub project: NameOrId<'static>,
161 /// The internal ID (`iid`) of the merge request.
162 pub merge_request: u64,
163}
164
165impl Endpoint for MergeRequestVersions {
166 fn method(&self) -> Method {
167 Method::GET
168 }
169
170 fn endpoint(&self) -> Cow<'static, str> {
171 format!(
172 "projects/{}/merge_requests/{}/versions",
173 self.project, self.merge_request,
174 )
175 .into()
176 }
177}
178
179/// Read one diff version of a merge request, with its `diffs`.
180///
181/// Maps to `GET /projects/:id/merge_requests/:merge_request/versions/:version_id`.
182///
183/// # Examples
184///
185/// ```no_run
186/// use ironflow_ops_gitlab::GitLab;
187/// use ironflow_ops_gitlab::endpoints::merge_requests::MergeRequestVersion;
188/// use gitlab::api::common::NameOrId;
189///
190/// # async fn example() -> Result<(), ironflow_core::error::OperationError> {
191/// let gitlab = GitLab::new("glpat-xxxx", "gitlab.com").await?;
192/// let endpoint = MergeRequestVersion {
193/// project: NameOrId::from(42),
194/// merge_request: 7,
195/// version: 3,
196/// };
197/// let op = gitlab.op(endpoint);
198/// # Ok(())
199/// # }
200/// ```
201///
202/// # Errors
203///
204/// Returns an error if the request fails (e.g. the version does not exist).
205pub struct MergeRequestVersion {
206 /// The project the merge request belongs to.
207 pub project: NameOrId<'static>,
208 /// The internal ID (`iid`) of the merge request.
209 pub merge_request: u64,
210 /// The ID of the diff version, from [`MergeRequestVersions`].
211 pub version: u64,
212}
213
214impl Endpoint for MergeRequestVersion {
215 fn method(&self) -> Method {
216 Method::GET
217 }
218
219 fn endpoint(&self) -> Cow<'static, str> {
220 format!(
221 "projects/{}/merge_requests/{}/versions/{}",
222 self.project, self.merge_request, self.version,
223 )
224 .into()
225 }
226}
227
228/// Delete a note of a merge request.
229///
230/// Maps to `DELETE /projects/:id/merge_requests/:merge_request/notes/:note_id`.
231/// GitLab answers `204 No Content`, which [`GitLab::op`](crate::GitLab::op)
232/// returns as `Value::Null`.
233///
234/// # Examples
235///
236/// ```no_run
237/// use ironflow_ops_gitlab::GitLab;
238/// use ironflow_ops_gitlab::endpoints::merge_requests::DeleteMergeRequestNote;
239/// use gitlab::api::common::NameOrId;
240///
241/// # async fn example() -> Result<(), ironflow_core::error::OperationError> {
242/// let gitlab = GitLab::new("glpat-xxxx", "gitlab.com").await?;
243/// let endpoint = DeleteMergeRequestNote {
244/// project: NameOrId::from(42),
245/// merge_request: 7,
246/// note: 1234,
247/// };
248/// let op = gitlab.op(endpoint);
249/// # Ok(())
250/// # }
251/// ```
252///
253/// # Errors
254///
255/// Returns an error if the request fails (e.g. the note does not exist or the
256/// token may not delete it).
257pub struct DeleteMergeRequestNote {
258 /// The project the merge request belongs to.
259 pub project: NameOrId<'static>,
260 /// The internal ID (`iid`) of the merge request.
261 pub merge_request: u64,
262 /// The ID of the note to delete.
263 pub note: u64,
264}
265
266impl Endpoint for DeleteMergeRequestNote {
267 fn method(&self) -> Method {
268 Method::DELETE
269 }
270
271 fn endpoint(&self) -> Cow<'static, str> {
272 format!(
273 "projects/{}/merge_requests/{}/notes/{}",
274 self.project, self.merge_request, self.note,
275 )
276 .into()
277 }
278}