1use std::fmt;
2use std::sync::atomic::{AtomicU64, Ordering};
3
4static NEXT_TASK_ID: AtomicU64 = AtomicU64::new(1);
5static NEXT_GLOBAL_PROGRESS_LISTENER_ID: AtomicU64 = AtomicU64::new(1);
6
7fn next_non_zero(counter: &AtomicU64) -> u64 {
8 counter
9 .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |current| {
10 Some(
11 current
12 .checked_add(1)
13 .filter(|next| *next != 0)
14 .unwrap_or(1),
15 )
16 })
17 .unwrap_or_else(|current| current)
18}
19
20#[derive(Clone, Copy, PartialEq, Eq, Hash)]
24pub struct TaskId(u64);
25
26impl TaskId {
27 pub(crate) fn new() -> Self {
29 Self(next_non_zero(&NEXT_TASK_ID))
30 }
31}
32
33impl fmt::Debug for TaskId {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 fmt::Debug::fmt(&self.0, f)
36 }
37}
38
39impl fmt::Display for TaskId {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 fmt::Display::fmt(&self.0, f)
42 }
43}
44
45#[derive(Clone, Copy, PartialEq, Eq, Hash)]
50pub struct GlobalProgressListenerId(u64);
51
52impl GlobalProgressListenerId {
53 pub(crate) fn new() -> Self {
55 Self(next_non_zero(&NEXT_GLOBAL_PROGRESS_LISTENER_ID))
56 }
57}
58
59impl fmt::Debug for GlobalProgressListenerId {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 fmt::Debug::fmt(&self.0, f)
62 }
63}