Skip to main content

wekan_cli/client/rules/
payloads.rs

1//! Explicit sparse trigger/action fields. Unmapped properties are rejected.
2use super::{present_nullable, validate_response_date};
3use serde::{Deserialize, Serialize};
4
5fn present_nullable_date<'de, D: serde::Deserializer<'de>>(
6    d: D,
7) -> Result<Option<Option<String>>, D::Error> {
8    let value = present_nullable::<D, String>(d)?;
9    if let Some(Some(date)) = &value {
10        validate_response_date(date).map_err(|()| {
11            serde::de::Error::custom("expected a valid Wekan date-time string or null")
12        })?;
13    }
14    Ok(value)
15}
16
17/// Wekan's schedule/relative-date consumers accept numbers and numeric text.
18#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
19#[serde(untagged)]
20pub enum RuleNumber {
21    Number(serde_json::Number),
22    Text(String),
23}
24
25#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
26#[serde(deny_unknown_fields, rename_all = "camelCase")]
27pub struct RuleTrigger {
28    #[serde(
29        default,
30        skip_serializing_if = "Option::is_none",
31        deserialize_with = "present_nullable"
32    )]
33    pub activity_type: Option<Option<String>>,
34    #[serde(
35        default,
36        skip_serializing_if = "Option::is_none",
37        deserialize_with = "present_nullable"
38    )]
39    pub user_id: Option<Option<String>>,
40    #[serde(
41        default,
42        skip_serializing_if = "Option::is_none",
43        deserialize_with = "present_nullable"
44    )]
45    pub username: Option<Option<String>>,
46    #[serde(
47        default,
48        skip_serializing_if = "Option::is_none",
49        deserialize_with = "present_nullable"
50    )]
51    pub list_name: Option<Option<String>>,
52    #[serde(
53        default,
54        skip_serializing_if = "Option::is_none",
55        deserialize_with = "present_nullable"
56    )]
57    pub old_list_name: Option<Option<String>>,
58    #[serde(
59        default,
60        skip_serializing_if = "Option::is_none",
61        deserialize_with = "present_nullable"
62    )]
63    pub swimlane_name: Option<Option<String>>,
64    #[serde(
65        default,
66        skip_serializing_if = "Option::is_none",
67        deserialize_with = "present_nullable"
68    )]
69    pub card_title: Option<Option<String>>,
70    #[serde(
71        default,
72        skip_serializing_if = "Option::is_none",
73        deserialize_with = "present_nullable"
74    )]
75    pub checklist_name: Option<Option<String>>,
76    #[serde(
77        default,
78        skip_serializing_if = "Option::is_none",
79        deserialize_with = "present_nullable"
80    )]
81    pub checklist_item_name: Option<Option<String>>,
82    #[serde(
83        default,
84        skip_serializing_if = "Option::is_none",
85        deserialize_with = "present_nullable"
86    )]
87    pub label_id: Option<Option<String>>,
88    #[serde(
89        default,
90        skip_serializing_if = "Option::is_none",
91        deserialize_with = "present_nullable"
92    )]
93    pub attachment_name: Option<Option<String>>,
94    #[serde(
95        default,
96        skip_serializing_if = "Option::is_none",
97        deserialize_with = "present_nullable"
98    )]
99    pub desc: Option<Option<String>>,
100    #[serde(
101        default,
102        skip_serializing_if = "Option::is_none",
103        deserialize_with = "present_nullable"
104    )]
105    pub schedule_kind: Option<Option<String>>,
106    #[serde(
107        default,
108        skip_serializing_if = "Option::is_none",
109        deserialize_with = "present_nullable"
110    )]
111    pub schedule_type: Option<Option<String>>,
112    #[serde(
113        default,
114        skip_serializing_if = "Option::is_none",
115        deserialize_with = "present_nullable"
116    )]
117    pub at_time: Option<Option<String>>,
118    #[serde(
119        default,
120        skip_serializing_if = "Option::is_none",
121        deserialize_with = "present_nullable"
122    )]
123    pub weekday: Option<Option<RuleNumber>>,
124    #[serde(
125        default,
126        skip_serializing_if = "Option::is_none",
127        deserialize_with = "present_nullable"
128    )]
129    pub day_of_month: Option<Option<RuleNumber>>,
130    #[serde(
131        default,
132        skip_serializing_if = "Option::is_none",
133        deserialize_with = "present_nullable"
134    )]
135    pub on_date: Option<Option<String>>,
136    #[serde(
137        default,
138        skip_serializing_if = "Option::is_none",
139        deserialize_with = "present_nullable"
140    )]
141    pub due_condition: Option<Option<String>>,
142    #[serde(
143        default,
144        skip_serializing_if = "Option::is_none",
145        deserialize_with = "present_nullable"
146    )]
147    pub days: Option<Option<RuleNumber>>,
148    #[serde(
149        default,
150        skip_serializing_if = "Option::is_none",
151        deserialize_with = "present_nullable"
152    )]
153    pub last_run_key: Option<Option<String>>,
154    #[serde(
155        default,
156        skip_serializing_if = "Option::is_none",
157        deserialize_with = "present_nullable"
158    )]
159    pub last_run_at: Option<Option<String>>,
160    #[serde(
161        default,
162        skip_serializing_if = "Option::is_none",
163        deserialize_with = "present_nullable"
164    )]
165    pub button_type: Option<Option<String>>,
166    #[serde(
167        default,
168        skip_serializing_if = "Option::is_none",
169        deserialize_with = "present_nullable"
170    )]
171    pub button_label: Option<Option<String>>,
172}
173
174#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
175#[serde(deny_unknown_fields, rename_all = "camelCase")]
176pub struct RuleAction {
177    #[serde(
178        default,
179        skip_serializing_if = "Option::is_none",
180        deserialize_with = "present_nullable"
181    )]
182    pub action_type: Option<Option<String>>,
183    #[serde(
184        default,
185        skip_serializing_if = "Option::is_none",
186        deserialize_with = "present_nullable"
187    )]
188    pub list_name: Option<Option<String>>,
189    #[serde(
190        default,
191        skip_serializing_if = "Option::is_none",
192        deserialize_with = "present_nullable"
193    )]
194    pub swimlane_name: Option<Option<String>>,
195    #[serde(
196        default,
197        skip_serializing_if = "Option::is_none",
198        deserialize_with = "present_nullable"
199    )]
200    pub card_name: Option<Option<String>>,
201    #[serde(
202        default,
203        skip_serializing_if = "Option::is_none",
204        deserialize_with = "present_nullable"
205    )]
206    pub from_list_name: Option<Option<String>>,
207    #[serde(
208        default,
209        skip_serializing_if = "Option::is_none",
210        deserialize_with = "present_nullable"
211    )]
212    pub checklist_name: Option<Option<String>>,
213    #[serde(
214        default,
215        skip_serializing_if = "Option::is_none",
216        deserialize_with = "present_nullable"
217    )]
218    pub check_item_name: Option<Option<String>>,
219    #[serde(
220        default,
221        skip_serializing_if = "Option::is_none",
222        deserialize_with = "present_nullable"
223    )]
224    pub checklist_items: Option<Option<String>>,
225    #[serde(
226        default,
227        skip_serializing_if = "Option::is_none",
228        deserialize_with = "present_nullable"
229    )]
230    pub date_field: Option<Option<String>>,
231    #[serde(
232        default,
233        skip_serializing_if = "Option::is_none",
234        deserialize_with = "present_nullable"
235    )]
236    pub unit: Option<Option<String>>,
237    #[serde(
238        default,
239        skip_serializing_if = "Option::is_none",
240        deserialize_with = "present_nullable"
241    )]
242    pub email_to: Option<Option<String>>,
243    #[serde(
244        default,
245        skip_serializing_if = "Option::is_none",
246        deserialize_with = "present_nullable"
247    )]
248    pub email_subject: Option<Option<String>>,
249    #[serde(
250        default,
251        skip_serializing_if = "Option::is_none",
252        deserialize_with = "present_nullable"
253    )]
254    pub email_msg: Option<Option<String>>,
255    #[serde(
256        default,
257        skip_serializing_if = "Option::is_none",
258        deserialize_with = "present_nullable"
259    )]
260    pub selected_color: Option<Option<String>>,
261    #[serde(
262        default,
263        skip_serializing_if = "Option::is_none",
264        deserialize_with = "present_nullable"
265    )]
266    pub label_id: Option<Option<String>>,
267    #[serde(
268        default,
269        skip_serializing_if = "Option::is_none",
270        deserialize_with = "present_nullable"
271    )]
272    pub username: Option<Option<String>>,
273    #[serde(
274        default,
275        skip_serializing_if = "Option::is_none",
276        deserialize_with = "present_nullable"
277    )]
278    pub sort_field: Option<Option<String>>,
279    #[serde(
280        default,
281        skip_serializing_if = "Option::is_none",
282        deserialize_with = "present_nullable"
283    )]
284    pub desc: Option<Option<String>>,
285    #[serde(
286        default,
287        skip_serializing_if = "Option::is_none",
288        deserialize_with = "present_nullable"
289    )]
290    pub days: Option<Option<RuleNumber>>,
291}
292
293#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
294#[serde(deny_unknown_fields, rename_all = "camelCase")]
295pub struct RuleTriggerInput {
296    #[serde(
297        default,
298        skip_serializing_if = "Option::is_none",
299        deserialize_with = "present_nullable"
300    )]
301    pub activity_type: Option<Option<String>>,
302    #[serde(
303        default,
304        skip_serializing_if = "Option::is_none",
305        deserialize_with = "present_nullable"
306    )]
307    pub user_id: Option<Option<String>>,
308    #[serde(
309        default,
310        skip_serializing_if = "Option::is_none",
311        deserialize_with = "present_nullable"
312    )]
313    pub username: Option<Option<String>>,
314    #[serde(
315        default,
316        skip_serializing_if = "Option::is_none",
317        deserialize_with = "present_nullable"
318    )]
319    pub list_name: Option<Option<String>>,
320    #[serde(
321        default,
322        skip_serializing_if = "Option::is_none",
323        deserialize_with = "present_nullable"
324    )]
325    pub old_list_name: Option<Option<String>>,
326    #[serde(
327        default,
328        skip_serializing_if = "Option::is_none",
329        deserialize_with = "present_nullable"
330    )]
331    pub swimlane_name: Option<Option<String>>,
332    #[serde(
333        default,
334        skip_serializing_if = "Option::is_none",
335        deserialize_with = "present_nullable"
336    )]
337    pub card_title: Option<Option<String>>,
338    #[serde(
339        default,
340        skip_serializing_if = "Option::is_none",
341        deserialize_with = "present_nullable"
342    )]
343    pub checklist_name: Option<Option<String>>,
344    #[serde(
345        default,
346        skip_serializing_if = "Option::is_none",
347        deserialize_with = "present_nullable"
348    )]
349    pub checklist_item_name: Option<Option<String>>,
350    #[serde(
351        default,
352        skip_serializing_if = "Option::is_none",
353        deserialize_with = "present_nullable"
354    )]
355    pub label_id: Option<Option<String>>,
356    #[serde(
357        default,
358        skip_serializing_if = "Option::is_none",
359        deserialize_with = "present_nullable"
360    )]
361    pub attachment_name: Option<Option<String>>,
362    #[serde(
363        default,
364        skip_serializing_if = "Option::is_none",
365        deserialize_with = "present_nullable"
366    )]
367    pub desc: Option<Option<String>>,
368    #[serde(
369        default,
370        skip_serializing_if = "Option::is_none",
371        deserialize_with = "present_nullable"
372    )]
373    pub schedule_kind: Option<Option<String>>,
374    #[serde(
375        default,
376        skip_serializing_if = "Option::is_none",
377        deserialize_with = "present_nullable"
378    )]
379    pub schedule_type: Option<Option<String>>,
380    #[serde(
381        default,
382        skip_serializing_if = "Option::is_none",
383        deserialize_with = "present_nullable"
384    )]
385    pub at_time: Option<Option<String>>,
386    #[serde(
387        default,
388        skip_serializing_if = "Option::is_none",
389        deserialize_with = "present_nullable"
390    )]
391    pub weekday: Option<Option<RuleNumber>>,
392    #[serde(
393        default,
394        skip_serializing_if = "Option::is_none",
395        deserialize_with = "present_nullable"
396    )]
397    pub day_of_month: Option<Option<RuleNumber>>,
398    #[serde(
399        default,
400        skip_serializing_if = "Option::is_none",
401        deserialize_with = "present_nullable"
402    )]
403    pub on_date: Option<Option<String>>,
404    #[serde(
405        default,
406        skip_serializing_if = "Option::is_none",
407        deserialize_with = "present_nullable"
408    )]
409    pub due_condition: Option<Option<String>>,
410    #[serde(
411        default,
412        skip_serializing_if = "Option::is_none",
413        deserialize_with = "present_nullable"
414    )]
415    pub days: Option<Option<RuleNumber>>,
416    #[serde(
417        default,
418        skip_serializing_if = "Option::is_none",
419        deserialize_with = "present_nullable"
420    )]
421    pub last_run_key: Option<Option<String>>,
422    #[serde(
423        default,
424        skip_serializing_if = "Option::is_none",
425        deserialize_with = "present_nullable_date"
426    )]
427    pub last_run_at: Option<Option<String>>,
428    #[serde(
429        default,
430        skip_serializing_if = "Option::is_none",
431        deserialize_with = "present_nullable"
432    )]
433    pub button_type: Option<Option<String>>,
434    #[serde(
435        default,
436        skip_serializing_if = "Option::is_none",
437        deserialize_with = "present_nullable"
438    )]
439    pub button_label: Option<Option<String>>,
440    #[serde(
441        default,
442        skip_serializing_if = "Option::is_none",
443        deserialize_with = "present_nullable"
444    )]
445    #[serde(rename = "_id")]
446    pub id: Option<Option<String>>,
447    #[serde(
448        default,
449        skip_serializing_if = "Option::is_none",
450        deserialize_with = "present_nullable"
451    )]
452    pub board_id: Option<Option<String>>,
453    #[serde(
454        default,
455        skip_serializing_if = "Option::is_none",
456        deserialize_with = "present_nullable"
457    )]
458    pub created_at: Option<Option<String>>,
459    #[serde(
460        default,
461        skip_serializing_if = "Option::is_none",
462        deserialize_with = "present_nullable"
463    )]
464    pub modified_at: Option<Option<String>>,
465    #[serde(
466        default,
467        skip_serializing_if = "Option::is_none",
468        deserialize_with = "present_nullable"
469    )]
470    pub updated_at: Option<Option<String>>,
471}
472
473#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
474#[serde(deny_unknown_fields, rename_all = "camelCase")]
475pub struct RuleActionInput {
476    #[serde(
477        default,
478        skip_serializing_if = "Option::is_none",
479        deserialize_with = "present_nullable"
480    )]
481    pub action_type: Option<Option<String>>,
482    #[serde(
483        default,
484        skip_serializing_if = "Option::is_none",
485        deserialize_with = "present_nullable"
486    )]
487    pub list_name: Option<Option<String>>,
488    #[serde(
489        default,
490        skip_serializing_if = "Option::is_none",
491        deserialize_with = "present_nullable"
492    )]
493    pub swimlane_name: Option<Option<String>>,
494    #[serde(
495        default,
496        skip_serializing_if = "Option::is_none",
497        deserialize_with = "present_nullable"
498    )]
499    pub card_name: Option<Option<String>>,
500    #[serde(
501        default,
502        skip_serializing_if = "Option::is_none",
503        deserialize_with = "present_nullable"
504    )]
505    pub from_list_name: Option<Option<String>>,
506    #[serde(
507        default,
508        skip_serializing_if = "Option::is_none",
509        deserialize_with = "present_nullable"
510    )]
511    pub checklist_name: Option<Option<String>>,
512    #[serde(
513        default,
514        skip_serializing_if = "Option::is_none",
515        deserialize_with = "present_nullable"
516    )]
517    pub check_item_name: Option<Option<String>>,
518    #[serde(
519        default,
520        skip_serializing_if = "Option::is_none",
521        deserialize_with = "present_nullable"
522    )]
523    pub checklist_items: Option<Option<String>>,
524    #[serde(
525        default,
526        skip_serializing_if = "Option::is_none",
527        deserialize_with = "present_nullable"
528    )]
529    pub date_field: Option<Option<String>>,
530    #[serde(
531        default,
532        skip_serializing_if = "Option::is_none",
533        deserialize_with = "present_nullable"
534    )]
535    pub unit: Option<Option<String>>,
536    #[serde(
537        default,
538        skip_serializing_if = "Option::is_none",
539        deserialize_with = "present_nullable"
540    )]
541    pub email_to: Option<Option<String>>,
542    #[serde(
543        default,
544        skip_serializing_if = "Option::is_none",
545        deserialize_with = "present_nullable"
546    )]
547    pub email_subject: Option<Option<String>>,
548    #[serde(
549        default,
550        skip_serializing_if = "Option::is_none",
551        deserialize_with = "present_nullable"
552    )]
553    pub email_msg: Option<Option<String>>,
554    #[serde(
555        default,
556        skip_serializing_if = "Option::is_none",
557        deserialize_with = "present_nullable"
558    )]
559    pub selected_color: Option<Option<String>>,
560    #[serde(
561        default,
562        skip_serializing_if = "Option::is_none",
563        deserialize_with = "present_nullable"
564    )]
565    pub label_id: Option<Option<String>>,
566    #[serde(
567        default,
568        skip_serializing_if = "Option::is_none",
569        deserialize_with = "present_nullable"
570    )]
571    pub username: Option<Option<String>>,
572    #[serde(
573        default,
574        skip_serializing_if = "Option::is_none",
575        deserialize_with = "present_nullable"
576    )]
577    pub sort_field: Option<Option<String>>,
578    #[serde(
579        default,
580        skip_serializing_if = "Option::is_none",
581        deserialize_with = "present_nullable"
582    )]
583    pub desc: Option<Option<String>>,
584    #[serde(
585        default,
586        skip_serializing_if = "Option::is_none",
587        deserialize_with = "present_nullable"
588    )]
589    pub days: Option<Option<RuleNumber>>,
590    #[serde(
591        default,
592        skip_serializing_if = "Option::is_none",
593        deserialize_with = "present_nullable"
594    )]
595    #[serde(rename = "_id")]
596    pub id: Option<Option<String>>,
597    #[serde(
598        default,
599        skip_serializing_if = "Option::is_none",
600        deserialize_with = "present_nullable"
601    )]
602    pub board_id: Option<Option<String>>,
603    #[serde(
604        default,
605        skip_serializing_if = "Option::is_none",
606        deserialize_with = "present_nullable"
607    )]
608    pub created_at: Option<Option<String>>,
609    #[serde(
610        default,
611        skip_serializing_if = "Option::is_none",
612        deserialize_with = "present_nullable"
613    )]
614    pub modified_at: Option<Option<String>>,
615    #[serde(
616        default,
617        skip_serializing_if = "Option::is_none",
618        deserialize_with = "present_nullable"
619    )]
620    pub updated_at: Option<Option<String>>,
621}