1use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use time::Duration;
8
9use crate::task::TaskDefinition;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
14#[must_use]
15pub struct ScheduleDefinition {
16 pub policy: SchedulePolicy,
18 pub immediate: bool,
21 #[serde(default)]
23 pub missed_tasks: MissedTasksPolicy,
24 pub new_task: NewTask,
26 #[serde(default)]
28 pub labels: HashMap<String, Value>,
29}
30
31impl ScheduleDefinition {
32 pub fn new(policy: SchedulePolicy, new_task: NewTask) -> Self {
34 Self {
35 missed_tasks: Default::default(),
36 policy,
37 new_task,
38 immediate: false,
39 labels: Default::default(),
40 }
41 }
42
43 pub fn immediate(mut self, immediate: bool) -> Self {
46 self.immediate = immediate;
47 self
48 }
49
50 pub fn on_missed_tasks(mut self, policy: MissedTasksPolicy) -> Self {
52 self.missed_tasks = policy;
53 self
54 }
55
56 pub fn with_label(mut self, name: &str, value: impl Serialize) -> Self {
62 self.labels
63 .insert(name.into(), serde_json::to_value(value).unwrap());
64 self
65 }
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "snake_case")]
74#[must_use]
75pub enum SchedulePolicy {
76 Repeat {
78 interval_ns: u64,
80 },
81 Cron {
83 expr: String,
85 },
86}
87
88impl SchedulePolicy {
89 #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
91 pub fn repeat(interval: Duration) -> Self {
92 Self::Repeat {
93 interval_ns: interval.whole_nanoseconds() as _,
94 }
95 }
96
97 pub fn cron(expr: &str) -> Result<Self, cron::error::Error> {
103 expr.parse::<cron::Schedule>()?;
104
105 Ok(Self::Cron {
106 expr: expr.to_string(),
107 })
108 }
109}
110
111#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
115#[serde(rename_all = "snake_case")]
116pub enum MissedTasksPolicy {
117 Burst,
119 #[default]
122 Skip,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127#[serde(rename_all = "snake_case")]
128pub enum NewTask {
129 Repeat {
131 task: TaskDefinition,
133 },
134}
135
136impl NewTask {
137 #[must_use]
139 pub fn repeat<T>(task: TaskDefinition<T>) -> Self {
140 Self::Repeat { task: task.cast() }
141 }
142}