use std::str::FromStr;
use chrono::{DateTime, Utc};
use cron::Schedule;
use runledger_postgres::jobs::JOB_SCHEDULE_MAX_JITTER_SECONDS;
use serde_json::Value;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CatalogJobScheduleSpec<'a> {
pub name: &'a str,
pub job_type: &'a str,
pub cron_expr: &'a str,
pub payload_template: &'a Value,
pub is_active: bool,
pub organization_id: Option<Uuid>,
pub max_jitter_seconds: i32,
pub next_fire_at: Option<DateTime<Utc>>,
}
impl<'a> CatalogJobScheduleSpec<'a> {
pub(super) fn validate_shape(&self) -> Result<(), &'static str> {
if self.name.trim().is_empty() {
return Err("name");
}
if self.name != self.name.trim() {
return Err("name");
}
if self.job_type.trim().is_empty() {
return Err("job_type");
}
if self.cron_expr.trim().is_empty() {
return Err("cron_expr");
}
if self.cron_expr != self.cron_expr.trim() {
return Err("cron_expr");
}
if Schedule::from_str(self.cron_expr).is_err() {
return Err("cron_expr");
}
if self.max_jitter_seconds < 0 {
return Err("max_jitter_seconds");
}
if self.max_jitter_seconds > JOB_SCHEDULE_MAX_JITTER_SECONDS {
return Err("max_jitter_seconds");
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct StoredCatalogJobScheduleSpec {
pub name: String,
pub job_type: String,
pub cron_expr: String,
pub payload_template: Value,
pub is_active: bool,
pub organization_id: Option<Uuid>,
pub max_jitter_seconds: i32,
pub next_fire_at: Option<DateTime<Utc>>,
}
impl<'a> From<&CatalogJobScheduleSpec<'a>> for StoredCatalogJobScheduleSpec {
fn from(spec: &CatalogJobScheduleSpec<'a>) -> Self {
Self {
name: spec.name.to_owned(),
job_type: spec.job_type.to_owned(),
cron_expr: spec.cron_expr.to_owned(),
payload_template: spec.payload_template.clone(),
is_active: spec.is_active,
organization_id: spec.organization_id,
max_jitter_seconds: spec.max_jitter_seconds,
next_fire_at: spec.next_fire_at,
}
}
}
impl StoredCatalogJobScheduleSpec {
pub(super) fn as_spec(&self) -> CatalogJobScheduleSpec<'_> {
CatalogJobScheduleSpec {
name: &self.name,
job_type: &self.job_type,
cron_expr: &self.cron_expr,
payload_template: &self.payload_template,
is_active: self.is_active,
organization_id: self.organization_id,
max_jitter_seconds: self.max_jitter_seconds,
next_fire_at: self.next_fire_at,
}
}
}