use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use time::Duration;
use crate::task::TaskDefinition;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[must_use]
pub struct ScheduleDefinition {
pub policy: SchedulePolicy,
pub immediate: bool,
#[serde(default)]
pub missed_tasks: MissedTasksPolicy,
pub new_task: NewTask,
#[serde(default)]
pub labels: HashMap<String, Value>,
}
impl ScheduleDefinition {
pub fn new(policy: SchedulePolicy, new_task: NewTask) -> Self {
Self {
missed_tasks: Default::default(),
policy,
new_task,
immediate: false,
labels: Default::default(),
}
}
pub fn immediate(mut self, immediate: bool) -> Self {
self.immediate = immediate;
self
}
pub fn on_missed_tasks(mut self, policy: MissedTasksPolicy) -> Self {
self.missed_tasks = policy;
self
}
pub fn with_label(mut self, name: &str, value: impl Serialize) -> Self {
self.labels
.insert(name.into(), serde_json::to_value(value).unwrap());
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[must_use]
pub enum SchedulePolicy {
Repeat {
interval_ns: u64,
},
Cron {
expr: String,
},
}
impl SchedulePolicy {
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn repeat(interval: Duration) -> Self {
Self::Repeat {
interval_ns: interval.whole_nanoseconds() as _,
}
}
pub fn cron(expr: &str) -> Result<Self, cron::error::Error> {
expr.parse::<cron::Schedule>()?;
Ok(Self::Cron {
expr: expr.to_string(),
})
}
}
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MissedTasksPolicy {
Burst,
#[default]
Skip,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NewTask {
Repeat {
task: TaskDefinition,
},
}
impl NewTask {
#[must_use]
pub fn repeat<T>(task: TaskDefinition<T>) -> Self {
Self::Repeat { task: task.cast() }
}
}