actionqueue_engine/derive/
once.rs1use actionqueue_core::ids::TaskId;
8use actionqueue_core::run::run_instance::RunInstance;
9
10use crate::derive::{map_run_construction_error, DerivationError, DerivationSuccess};
11use crate::time::clock::Clock;
12
13pub fn derive_once(
17 clock: &impl Clock,
18 task_id: TaskId,
19 already_derived: u32,
20) -> Result<DerivationSuccess, DerivationError> {
21 let now = clock.now();
22
23 if already_derived >= 1 {
25 return Ok(DerivationSuccess::new(Vec::new(), 1));
26 }
27
28 let run = RunInstance::new_scheduled(
30 task_id, now, now, )
33 .map_err(|source| map_run_construction_error(task_id, source))?;
34
35 Ok(DerivationSuccess::new(vec![run], 1))
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn derive_once_creates_one_run() {
44 let clock = crate::time::clock::MockClock::new(1000);
45 let task_id = TaskId::new();
46
47 let result = derive_once(&clock, task_id, 0).unwrap();
48
49 assert_eq!(result.derived().len(), 1);
50 assert_eq!(result.already_derived(), 1);
51 assert_eq!(result.derived()[0].task_id(), task_id);
52 assert_eq!(result.derived()[0].state(), actionqueue_core::run::state::RunState::Scheduled);
53 assert_eq!(result.derived()[0].scheduled_at(), 1000);
54 assert_eq!(result.derived()[0].created_at(), 1000);
55 }
56
57 #[test]
58 fn derive_once_does_not_duplicate() {
59 let clock = crate::time::clock::MockClock::new(1000);
60 let task_id = TaskId::new();
61
62 let result1 = derive_once(&clock, task_id, 0).unwrap();
64 assert_eq!(result1.derived().len(), 1);
65
66 let result2 = derive_once(&clock, task_id, 1).unwrap();
68
69 assert_eq!(result2.derived().len(), 0);
70 assert_eq!(result2.already_derived(), 1);
71 }
72
73 #[test]
74 fn derive_once_returns_typed_error_for_nil_task_id_instead_of_panicking() {
75 let clock = crate::time::clock::MockClock::new(1000);
76 let task_id = "00000000-0000-0000-0000-000000000000"
77 .parse::<TaskId>()
78 .expect("nil task id literal must parse");
79
80 let result = derive_once(&clock, task_id, 0);
81
82 assert_eq!(result, Err(DerivationError::InvalidTaskIdForRunConstruction { task_id }));
83 }
84}