spacetimedb_primitives/
ids.rs

1//! Provides identifiers such as `TableId`.
2
3use core::fmt;
4
5macro_rules! system_id {
6    ($(#[$($doc_comment:tt)*])* pub struct $name:ident(pub $backing_ty:ty);) => {
7
8        $(#[$($doc_comment)*])*
9        #[derive(Debug, Default, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
10        #[repr(transparent)]
11        pub struct $name(pub $backing_ty);
12
13        impl From<$backing_ty> for $name {
14            fn from(value: $backing_ty) -> Self {
15                Self(value)
16            }
17        }
18        impl From<$name> for $backing_ty {
19            fn from(value: $name) -> Self {
20                value.0
21            }
22        }
23
24        impl $name {
25            /// Convert `self` to a `usize` suitable for indexing into an array.
26            pub fn idx(self) -> usize {
27                self.0 as usize
28            }
29
30        }
31
32        impl nohash_hasher::IsEnabled for $name {}
33
34        impl From<usize> for $name {
35            fn from(value: usize) -> Self {
36                Self(value as _)
37            }
38        }
39
40        impl fmt::Display for $name {
41            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42                write!(f, "{}", self.0)
43            }
44        }
45
46        // Defined so that e.g., `0.into()` is possible.
47        impl From<i32> for $name {
48            fn from(value: i32) -> Self {
49                Self(value as _)
50            }
51        }
52
53        #[cfg(feature = "memory-usage")]
54        impl spacetimedb_memory_usage::MemoryUsage for $name {}
55    };
56}
57// TODO(1.0): convert this into a proper trait.
58macro_rules! auto_inc_system_id {
59    ($name:ident) => {
60        impl $name {
61            /// The sentinel value for this type.
62            /// This will be initialized to a valid ID upon insertion into a system table as a primary key.
63            pub const SENTINEL: Self = Self(0);
64
65            /// Check if this ID is the sentinel value.
66            pub fn is_sentinel(self) -> bool {
67                self == Self::SENTINEL
68            }
69        }
70    };
71}
72
73system_id! {
74    /// An identifier for a table, unique within a database.
75    pub struct TableId(pub u32);
76}
77auto_inc_system_id!(TableId);
78
79system_id! {
80    /// An identifier for a sequence, unique within a database.
81    pub struct SequenceId(pub u32);
82}
83auto_inc_system_id!(SequenceId);
84
85system_id! {
86    /// An identifier for an index, unique within a database.
87    pub struct IndexId(pub u32);
88}
89auto_inc_system_id!(IndexId);
90
91system_id! {
92    /// An identifier for a constraint, unique within a database.
93    pub struct ConstraintId(pub u32);
94}
95auto_inc_system_id!(ConstraintId);
96
97system_id! {
98    /// An identifier for a schedule, unique within a database.
99    pub struct ScheduleId(pub u32);
100}
101auto_inc_system_id!(ScheduleId);
102
103system_id! {
104    /// The position of a column within a table.
105    ///
106    /// A `ColId` does NOT uniquely identify a column within a database!
107    /// A pair `(TableId, ColId)` is required for this.
108    /// Each table will have columns with `ColId` values ranging from `0` to `n-1`, where `n` is the number of columns in the table.
109    /// A table may have at most `u16::MAX` columns.
110    pub struct ColId(pub u16);
111}
112// ColId works differently from other system IDs and is not auto-incremented.
113
114system_id! {
115    /// The index of a reducer as defined in a module's reducers list.
116    // This is never stored in a system table, but is useful to have defined here.
117    pub struct ReducerId(pub u32);
118}