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}
54// TODO(1.0): convert this into a proper trait.
55macro_rules! auto_inc_system_id {
56    ($name:ident) => {
57        impl $name {
58            /// The sentinel value for this type.
59            /// This will be initialized to a valid ID upon insertion into a system table as a primary key.
60            pub const SENTINEL: Self = Self(0);
61
62            /// Check if this ID is the sentinel value.
63            pub fn is_sentinel(self) -> bool {
64                self == Self::SENTINEL
65            }
66        }
67    };
68}
69
70system_id! {
71    /// An identifier for a table, unique within a database.
72    pub struct TableId(pub u32);
73}
74auto_inc_system_id!(TableId);
75
76system_id! {
77    /// An identifier for a sequence, unique within a database.
78    pub struct SequenceId(pub u32);
79}
80auto_inc_system_id!(SequenceId);
81
82system_id! {
83    /// An identifier for an index, unique within a database.
84    pub struct IndexId(pub u32);
85}
86auto_inc_system_id!(IndexId);
87
88system_id! {
89    /// An identifier for a constraint, unique within a database.
90    pub struct ConstraintId(pub u32);
91}
92auto_inc_system_id!(ConstraintId);
93
94system_id! {
95    /// An identifier for a schedule, unique within a database.
96    pub struct ScheduleId(pub u32);
97}
98auto_inc_system_id!(ScheduleId);
99
100system_id! {
101    /// The position of a column within a table.
102    ///
103    /// A `ColId` does NOT uniquely identify a column within a database!
104    /// A pair `(TableId, ColId)` is required for this.
105    /// Each table will have columns with `ColId` values ranging from `0` to `n-1`, where `n` is the number of columns in the table.
106    /// A table may have at most `u16::MAX` columns.
107    pub struct ColId(pub u16);
108}
109// ColId works differently from other system IDs and is not auto-incremented.
110
111system_id! {
112    /// The index of a reducer as defined in a module's reducers list.
113    // This is never stored in a system table, but is useful to have defined here.
114    pub struct ReducerId(pub u32);
115}