extern crate chrono;
extern crate cron;
use crate::task::Task;
use chrono::prelude::*;
use chrono::DateTime;
use cron::Schedule;
use log::debug;
pub struct TaskGenerator<'a, T>
where
T: TimeZone,
{
discovery_function: Box<dyn (FnMut() -> Option<Task<'a, T>>) + 'a>,
schedule: Schedule,
timezone: T,
pub(crate) next_exec: DateTime<T>,
}
impl<'a, T> TaskGenerator<'a, T>
where
T: TimeZone + Clone,
{
pub fn new<F>(expression: &str, timezone: T, function: F) -> TaskGenerator<'a, T>
where
F: (FnMut() -> Option<Task<'a, T>>) + 'a,
{
let schedule: Schedule = expression.parse().unwrap();
TaskGenerator {
discovery_function: Box::new(function),
schedule: expression.parse().unwrap(),
timezone: timezone.clone(),
next_exec: schedule.upcoming(timezone).next().unwrap(),
}
}
pub(crate) fn run(&mut self) -> Option<Task<'a, T>> {
debug!("Executing discovery function.");
self.next_exec = self
.schedule
.upcoming(self.timezone.clone())
.next()
.unwrap();
match (self.discovery_function)() {
Some(t) => {
debug!("A task was found, adding it to the queue...");
return Some(t);
}
None => {
debug!("No task was generated.");
None
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
use chrono::Local;
#[test]
fn test_task_generation_with_result() {
let mut task_gen = TaskGenerator::new("* * * * * * *", Local, || {
Some(Task::new("* * * * * * *", None, Some(1), Local))
});
assert!(!task_gen.run().is_none());
}
#[test]
fn test_task_generation_without_result() {
let mut task_gen = TaskGenerator::new("* * * * * * *", Local, || None);
assert!(task_gen.run().is_none());
}
}