spacetimedb_primitives/
ids.rs

1//! Provides identifiers such as `TableId`.
2
3use core::fmt;
4
5use enum_as_inner::EnumAsInner;
6
7macro_rules! system_id {
8    ($(#[$($doc_comment:tt)*])* pub struct $name:ident(pub $backing_ty:ty);) => {
9
10        $(#[$($doc_comment)*])*
11        #[derive(Debug, Default, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
12        #[repr(transparent)]
13        pub struct $name(pub $backing_ty);
14
15        impl From<$backing_ty> for $name {
16            fn from(value: $backing_ty) -> Self {
17                Self(value)
18            }
19        }
20        impl From<$name> for $backing_ty {
21            fn from(value: $name) -> Self {
22                value.0
23            }
24        }
25
26        impl $name {
27            /// Convert `self` to a `usize` suitable for indexing into an array.
28            pub fn idx(self) -> usize {
29                self.0 as usize
30            }
31
32        }
33
34        impl nohash_hasher::IsEnabled for $name {}
35
36        impl From<usize> for $name {
37            fn from(value: usize) -> Self {
38                Self(value as _)
39            }
40        }
41
42        impl fmt::Display for $name {
43            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44                write!(f, "{}", self.0)
45            }
46        }
47
48        // Defined so that e.g., `0.into()` is possible.
49        impl From<i32> for $name {
50            fn from(value: i32) -> Self {
51                Self(value as _)
52            }
53        }
54
55        #[cfg(feature = "memory-usage")]
56        impl spacetimedb_memory_usage::MemoryUsage for $name {}
57    };
58}
59// TODO(1.0): convert this into a proper trait.
60macro_rules! auto_inc_system_id {
61    ($name:ident) => {
62        impl $name {
63            /// The sentinel value for this type.
64            /// This will be initialized to a valid ID upon insertion into a system table as a primary key.
65            pub const SENTINEL: Self = Self(0);
66
67            /// Check if this ID is the sentinel value.
68            pub fn is_sentinel(self) -> bool {
69                self == Self::SENTINEL
70            }
71        }
72    };
73}
74
75system_id! {
76    /// An identifier for a table, unique within a database.
77    pub struct TableId(pub u32);
78}
79auto_inc_system_id!(TableId);
80
81system_id! {
82    /// An identifier for a view, unique within a database.
83    /// It is stored in the db as the primary key column of `st_view`.
84    pub struct ViewId(pub u32);
85}
86auto_inc_system_id!(ViewId);
87
88system_id! {
89    /// An identifier for a list of arguments passed to a view.
90    pub struct ArgId(pub u64);
91}
92auto_inc_system_id!(ArgId);
93
94system_id! {
95    /// An identifier for a sequence, unique within a database.
96    pub struct SequenceId(pub u32);
97}
98auto_inc_system_id!(SequenceId);
99
100system_id! {
101    /// An identifier for an index, unique within a database.
102    pub struct IndexId(pub u32);
103}
104auto_inc_system_id!(IndexId);
105
106system_id! {
107    /// An identifier for a constraint, unique within a database.
108    pub struct ConstraintId(pub u32);
109}
110auto_inc_system_id!(ConstraintId);
111
112system_id! {
113    /// An identifier for a schedule, unique within a database.
114    pub struct ScheduleId(pub u32);
115}
116auto_inc_system_id!(ScheduleId);
117
118system_id! {
119    /// The position of a column within a table.
120    ///
121    /// A `ColId` does NOT uniquely identify a column within a database!
122    /// A pair `(TableId, ColId)` is required for this.
123    /// Each table will have columns with `ColId` values ranging from `0` to `n-1`, where `n` is the number of columns in the table.
124    /// A table may have at most `u16::MAX` columns.
125    pub struct ColId(pub u16);
126}
127// ColId works differently from other system IDs and is not auto-incremented.
128
129system_id! {
130    /// The index of a reducer as defined in a module's reducers list.
131    // This is never stored in a system table, but is useful to have defined here.
132    pub struct ReducerId(pub u32);
133}
134
135system_id! {
136    /// The index of a procedure as defined in a module's procedure list.
137    // This is never stored in a system table, but is useful to have defined here.
138    pub struct ProcedureId(pub u32);
139}
140
141system_id! {
142    /// The index of a view as defined in a module's view lists.
143    ///
144    /// Unlike reducers and procedures, the module maintains two lists for views.
145    /// One for `ViewContext` and the other for `AnonymousViewContext`.
146    /// As such, this index does not uniquely identify a view on its own.
147    /// You must know which list this index refers to.
148    ///
149    // This is never stored in a system table, but is useful to have defined here.
150    pub struct ViewFnPtr(pub u32);
151}
152
153/// An id for a function exported from a module, which may be a reducer or a procedure.
154// This is never stored in a system table,
155// but is useful to have defined here to provide a shared language for downstream crates.
156#[derive(Clone, Copy, Debug, EnumAsInner)]
157pub enum FunctionId {
158    Reducer(ReducerId),
159    Procedure(ProcedureId),
160}