Skip to main content

dataflow_rs/base/
ids.rs

1//! Opaque identities of programs and the positions within them.
2
3use serde::{Deserialize, Serialize};
4use std::sync::atomic::{AtomicU64, Ordering};
5
6static NEXT_PROGRAM: AtomicU64 = AtomicU64::new(1);
7
8/// The identity of one compiled program, unique within the process.
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
10pub struct ProgramId(u64);
11
12impl ProgramId {
13    /// The next unused identity.
14    pub(crate) fn next() -> Self {
15        Self(NEXT_PROGRAM.fetch_add(1, Ordering::Relaxed))
16    }
17
18    /// The identity as a number.
19    pub fn index(self) -> u64 {
20        self.0
21    }
22}
23
24/// The position of a workflow within a program. Serialized as its number,
25/// and read from one.
26#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
27#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
28#[serde(transparent)]
29pub struct WorkflowIx(u32);
30
31impl WorkflowIx {
32    /// The workflow at position `index`.
33    pub(crate) fn new(index: u32) -> Self {
34        Self(index)
35    }
36
37    /// The position as a number.
38    pub fn index(self) -> u32 {
39        self.0
40    }
41}
42
43/// The position of a task within a program. Serialized as its number, and
44/// read from one: a position read back names a task only in the program
45/// that wrote it.
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
47#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
48#[serde(transparent)]
49pub struct TaskIx(u32);
50
51impl TaskIx {
52    /// The task at position `index`.
53    pub(crate) fn new(index: u32) -> Self {
54        Self(index)
55    }
56
57    /// The position as a number.
58    pub fn index(self) -> u32 {
59        self.0
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn program_ids_are_distinct() {
69        assert_ne!(ProgramId::next(), ProgramId::next());
70        assert!(ProgramId::next().index() > 0);
71    }
72
73    #[test]
74    fn a_position_is_its_number() {
75        assert_eq!(WorkflowIx::new(3).index(), 3);
76        assert_eq!(TaskIx::new(7).index(), 7);
77        assert!(TaskIx::new(1) < TaskIx::new(2));
78    }
79}