reifydb_sub_task/
schedule.rs1use std::time::{Duration, Instant};
2
3#[derive(Debug, Clone)]
5pub enum Schedule {
6 FixedInterval(Duration),
8 Once(Duration),
10}
11
12impl Schedule {
13 pub fn next_execution(&self, after: Instant) -> Option<Instant> {
16 match self {
17 Schedule::FixedInterval(duration) => Some(after + *duration),
18 Schedule::Once(_) => None,
19 }
20 }
21
22 pub fn initial_delay(&self) -> Duration {
24 match self {
25 Schedule::FixedInterval(duration) => *duration,
26 Schedule::Once(delay) => *delay,
27 }
28 }
29
30 pub fn validate(&self) -> Result<(), String> {
32 match self {
33 Schedule::FixedInterval(duration) => {
34 if duration.is_zero() {
35 return Err("FixedInterval duration cannot be zero".to_string());
36 }
37 Ok(())
38 }
39 Schedule::Once(delay) => {
40 if delay.is_zero() {
41 return Err("Once delay cannot be zero".to_string());
42 }
43 Ok(())
44 }
45 }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_fixed_interval_next_execution() {
55 let schedule = Schedule::FixedInterval(Duration::from_secs(10));
56 let now = Instant::now();
57 let next = schedule.next_execution(now);
58 assert!(next.is_some());
59 assert_eq!(next.unwrap(), now + Duration::from_secs(10));
60 }
61
62 #[test]
63 fn test_once_next_execution() {
64 let schedule = Schedule::Once(Duration::from_secs(5));
65 let now = Instant::now();
66 let next = schedule.next_execution(now);
67 assert!(next.is_none());
68 }
69
70 #[test]
71 fn test_initial_delay() {
72 let interval = Schedule::FixedInterval(Duration::from_secs(30));
73 assert_eq!(interval.initial_delay(), Duration::from_secs(30));
74
75 let once = Schedule::Once(Duration::from_secs(5));
76 assert_eq!(once.initial_delay(), Duration::from_secs(5));
77 }
78
79 #[test]
80 fn test_validation() {
81 let valid = Schedule::FixedInterval(Duration::from_secs(1));
82 assert!(valid.validate().is_ok());
83
84 let invalid = Schedule::FixedInterval(Duration::ZERO);
85 assert!(invalid.validate().is_err());
86 }
87}