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