1use crate::{Client, ClientError, proto};
2use serde::Serialize;
3
4#[derive(Debug, Clone)]
6pub struct JobResultCorrections {
7 assignee: Option<String>,
8 due_date: Option<String>,
9 follow_up_date: Option<String>,
10 candidate_users: Option<Vec<String>>,
11 candidate_groups: Option<Vec<String>>,
12 priority: Option<i32>,
13}
14
15#[derive(Debug, Clone)]
17pub struct JobResult {
18 denied: Option<bool>,
20 corrections: Option<JobResultCorrections>,
22}
23
24#[derive(Debug, Clone)]
26pub struct JobResultBuilder {
27 source_request: CompleteJobRequest<WithKey>,
28 job_result: Option<JobResult>,
29}
30
31impl JobResultBuilder {
32 fn new(source_request: CompleteJobRequest<WithKey>) -> JobResultBuilder {
33 JobResultBuilder {
34 source_request,
35 job_result: None,
36 }
37 }
38
39 pub fn with_denied(mut self, denied: bool) -> Self {
49 if let Some(job_result) = self.job_result.as_mut() {
50 job_result.denied = Some(denied);
51 } else {
52 self.job_result = Some(JobResult {
53 denied: Some(denied),
54 corrections: None,
55 });
56 }
57
58 self
59 }
60
61 fn ensure_corrections(&mut self) -> &mut JobResultCorrections {
70 if self.job_result.is_none() {
71 self.job_result = Some(JobResult {
72 denied: None,
73 corrections: Some(JobResultCorrections {
74 assignee: None,
75 due_date: None,
76 follow_up_date: None,
77 candidate_users: None,
78 candidate_groups: None,
79 priority: None,
80 }),
81 });
82 }
83
84 let job_result = self.job_result.as_mut().unwrap();
85 if job_result.corrections.is_none() {
86 job_result.corrections = Some(JobResultCorrections {
87 assignee: None,
88 due_date: None,
89 follow_up_date: None,
90 candidate_users: None,
91 candidate_groups: None,
92 priority: None,
93 });
94 }
95
96 job_result.corrections.as_mut().unwrap()
97 }
98
99 pub fn with_assignee(mut self, assignee: String) -> Self {
109 self.ensure_corrections().assignee = Some(assignee);
110 self
111 }
112
113 pub fn with_due_date(mut self, due_date: String) -> Self {
123 self.ensure_corrections().due_date = Some(due_date);
124 self
125 }
126
127 pub fn with_follow_up_date(mut self, follow_up_date: String) -> Self {
137 self.ensure_corrections().follow_up_date = Some(follow_up_date);
138 self
139 }
140
141 pub fn with_candidate_users(mut self, candidate_users: Vec<String>) -> Self {
151 self.ensure_corrections().candidate_users = Some(candidate_users);
152 self
153 }
154
155 pub fn with_candidate_groups(mut self, candidate_groups: Vec<String>) -> Self {
165 self.ensure_corrections().candidate_groups = Some(candidate_groups);
166 self
167 }
168
169 pub fn with_priority(mut self, priority: i32) -> Self {
179 self.ensure_corrections().priority = Some(priority);
180 self
181 }
182
183 pub fn build(mut self) -> CompleteJobRequest<WithKey> {
191 self.source_request.result = self.job_result;
192 self.source_request
193 }
194}
195
196#[derive(Debug, Clone)]
197pub struct Initial;
198
199#[derive(Debug, Clone)]
200pub struct WithKey;
201
202pub trait CompleteJobRequestState {}
203impl CompleteJobRequestState for Initial {}
204impl CompleteJobRequestState for WithKey {}
205
206#[derive(Debug, Clone)]
218pub struct CompleteJobRequest<T: CompleteJobRequestState> {
219 client: Client,
220 job_key: i64,
221 variables: serde_json::Value,
222 result: Option<JobResult>,
223 _state: std::marker::PhantomData<T>,
224}
225
226impl<T: CompleteJobRequestState> CompleteJobRequest<T> {
227 pub(crate) fn new(client: Client) -> CompleteJobRequest<Initial> {
228 CompleteJobRequest {
229 client,
230 job_key: 0,
231 variables: serde_json::Value::default(),
232 result: None,
233 _state: std::marker::PhantomData,
234 }
235 }
236
237 fn transition<NewState: CompleteJobRequestState>(self) -> CompleteJobRequest<NewState> {
238 CompleteJobRequest {
239 client: self.client,
240 job_key: self.job_key,
241 variables: self.variables,
242 result: self.result,
243 _state: std::marker::PhantomData,
244 }
245 }
246}
247
248impl CompleteJobRequest<Initial> {
249 pub fn with_job_key(mut self, job_key: i64) -> CompleteJobRequest<WithKey> {
259 self.job_key = job_key;
260 self.transition()
261 }
262}
263
264impl CompleteJobRequest<WithKey> {
265 pub fn with_variables<T: Serialize>(mut self, data: T) -> Result<Self, ClientError> {
275 self.variables = serde_json::to_value(data)
276 .map_err(|e| ClientError::SerializationFailed { source: e })?;
277 Ok(self)
278 }
279
280 pub fn with_job_result(self) -> JobResultBuilder {
286 JobResultBuilder::new(self)
287 }
288
289 pub async fn send(mut self) -> Result<CompleteJobResponse, ClientError> {
295 let res = self
296 .client
297 .gateway_client
298 .complete_job(proto::CompleteJobRequest {
299 job_key: self.job_key,
300 variables: self.variables.to_string(),
301 result: self.result.map(|x| proto::JobResult {
302 denied: x.denied,
303 corrections: x.corrections.map(|c| proto::JobResultCorrections {
304 assignee: c.assignee,
305 due_date: c.due_date,
306 follow_up_date: c.follow_up_date,
307 candidate_users: c.candidate_users.map(|u| proto::StringList { values: u }),
308 candidate_groups: c
309 .candidate_groups
310 .map(|g| proto::StringList { values: g }),
311 priority: c.priority,
312 }),
313 }),
314 })
315 .await?;
316
317 Ok(res.into_inner().into())
318 }
319}
320
321#[derive(Debug, Clone)]
323pub struct CompleteJobResponse {}
324
325impl From<proto::CompleteJobResponse> for CompleteJobResponse {
326 fn from(_value: proto::CompleteJobResponse) -> CompleteJobResponse {
327 CompleteJobResponse {}
328 }
329}