use super::Schedule;
use std::{str::FromStr, time::Duration};
pub struct CronSchedule {
cron: cron::Schedule,
}
impl CronSchedule {
pub fn from_cron_str(cron_str: impl AsRef<str>) -> Result<Self, cron::error::Error> {
let cron = cron::Schedule::from_str(cron_str.as_ref())?;
Ok(Self { cron })
}
pub fn from_cron_schedule(cron: cron::Schedule) -> Self {
Self { cron }
}
fn calculate_next(&self) -> Option<Duration> {
let dt = self.cron.upcoming(chrono::Utc).next()?;
let now = chrono::Utc::now();
let delta = dt.signed_duration_since(&now);
Some(delta.to_std().unwrap_or(Duration::from_secs(0)))
}
}
impl<T> Schedule<T> for CronSchedule {
fn initial(&self) -> Option<Duration> {
self.calculate_next()
}
fn next(&self, _: T) -> Option<Duration> {
self.calculate_next()
}
}