Skip to main content

busybeaver/
task.rs

1use crate::fixed_count_task::FixedCountTask;
2use crate::periodic_task::PeriodicTask;
3use crate::range_interval_task::RangeIntervalTask;
4use crate::time_interval_task::TimeIntervalTask;
5use std::sync::atomic::Ordering;
6use uuid::Uuid;
7
8/// Unique task identifier (16-byte UUID, no heap allocation).
9#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
10pub struct TaskId(Uuid);
11
12impl TaskId {
13    #[inline]
14    pub(crate) fn new() -> Self {
15        TaskId(Uuid::new_v4())
16    }
17}
18
19impl Default for TaskId {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl std::fmt::Display for TaskId {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        self.0.fmt(f)
28    }
29}
30
31pub enum Task {
32    TimeInterval(TimeIntervalTask),
33    RangeInterval(RangeIntervalTask),
34    FixedCount(FixedCountTask),
35    Periodic(PeriodicTask),
36}
37
38impl Task {
39    pub fn id(&self) -> &TaskId {
40        match self {
41            Task::TimeInterval(s) => &s.id,
42            Task::RangeInterval(s) => &s.id,
43            Task::FixedCount(s) => &s.id,
44            Task::Periodic(s) => &s.id,
45        }
46    }
47    #[inline]
48    pub fn tag(&self) -> &str {
49        match self {
50            Task::TimeInterval(s) => s.tag.as_ref().map(|s| s.as_str()).unwrap_or(""),
51            Task::RangeInterval(s) => s.tag.as_ref().map(|s| s.as_str()).unwrap_or(""),
52            Task::FixedCount(s) => s.tag.as_ref().map(|s| s.as_str()).unwrap_or(""),
53            Task::Periodic(s) => s.tag.as_ref().map(|s| s.as_str()).unwrap_or(""),
54        }
55    }
56    #[inline]
57    pub fn interrupted(&self) -> bool {
58        match self {
59            Task::TimeInterval(s) => s.interrupted.load(Ordering::Relaxed),
60            Task::RangeInterval(s) => s.interrupted.load(Ordering::Relaxed),
61            Task::FixedCount(s) => s.interrupted.load(Ordering::Relaxed),
62            Task::Periodic(s) => s.interrupted.load(Ordering::Relaxed),
63        }
64    }
65    #[inline]
66    pub(crate) fn set_interrupted(&self, v: bool) {
67        match self {
68            Task::TimeInterval(s) => s.interrupted.store(v, Ordering::Release),
69            Task::RangeInterval(s) => s.interrupted.store(v, Ordering::Release),
70            Task::FixedCount(s) => s.interrupted.store(v, Ordering::Release),
71            Task::Periodic(s) => s.interrupted.store(v, Ordering::Release),
72        }
73    }
74    /// Marks as interrupted and calls the listener's `on_interrupt` if present.
75    pub(crate) fn interrupt(&self) {
76        self.set_interrupted(true);
77        match self {
78            Task::TimeInterval(s) => {
79                if let Some(l) = &s.listener {
80                    l.on_interrupt();
81                }
82            }
83            Task::RangeInterval(s) => {
84                if let Some(l) = &s.listener {
85                    l.on_interrupt();
86                }
87            }
88            Task::FixedCount(s) => {
89                if let Some(l) = &s.listener {
90                    l.on_interrupt();
91                }
92            }
93            Task::Periodic(s) => {
94                if let Some(l) = &s.listener {
95                    l.on_interrupt();
96                }
97            }
98        }
99    }
100}