bsv_wallet_toolbox/monitor/tasks/
task_clock.rs1use async_trait::async_trait;
6
7use crate::error::WalletError;
8use crate::monitor::helpers::now_msecs;
9use crate::monitor::task_trait::WalletMonitorTask;
10use crate::monitor::ONE_MINUTE;
11
12pub struct TaskClock {
16 next_minute: u64,
18}
19
20impl TaskClock {
21 pub fn new() -> Self {
23 Self {
24 next_minute: Self::get_next_minute(),
25 }
26 }
27
28 fn get_next_minute() -> u64 {
29 let now = now_msecs();
30 ((now / ONE_MINUTE) + 1) * ONE_MINUTE
32 }
33}
34
35#[async_trait]
36impl WalletMonitorTask for TaskClock {
37 fn name(&self) -> &str {
38 "Clock"
39 }
40
41 fn trigger(&mut self, _now_msecs: u64) -> bool {
42 now_msecs() > self.next_minute
43 }
44
45 async fn run_task(&mut self) -> Result<String, WalletError> {
46 let dt =
47 chrono::DateTime::from_timestamp_millis(self.next_minute as i64).unwrap_or_default();
48 let log = dt.to_rfc3339();
49 self.next_minute = Self::get_next_minute();
50 Ok(log)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_clock_trigger_before_next_minute() {
60 let mut clock = TaskClock::new();
61 assert!(
63 clock.next_minute > now_msecs(),
64 "next_minute should be in the future"
65 );
66 assert!(!clock.trigger(now_msecs()));
67 }
68
69 #[tokio::test]
70 async fn test_clock_run_task_returns_timestamp() {
71 let mut clock = TaskClock::new();
72 let result = clock.run_task().await.unwrap();
73 assert!(!result.is_empty());
75 assert!(
76 result.contains("T"),
77 "Expected ISO timestamp, got: {}",
78 result
79 );
80 }
81
82 #[test]
83 fn test_clock_name() {
84 let clock = TaskClock::new();
85 assert_eq!(clock.name(), "Clock");
86 }
87}