spacetimedb_primitives/
ids.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Provides identifiers such as `TableId`.

use core::fmt;

macro_rules! system_id {
    ($(#[$($doc_comment:tt)*])* pub struct $name:ident(pub $backing_ty:ty);) => {

        $(#[$($doc_comment)*])*
        #[derive(Debug, Default, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
        #[repr(transparent)]
        pub struct $name(pub $backing_ty);

        impl From<$backing_ty> for $name {
            fn from(value: $backing_ty) -> Self {
                Self(value)
            }
        }
        impl From<$name> for $backing_ty {
            fn from(value: $name) -> Self {
                value.0
            }
        }

        impl $name {
            /// Convert `self` to a `usize` suitable for indexing into an array.
            pub fn idx(self) -> usize {
                self.0 as usize
            }

        }

        impl nohash_hasher::IsEnabled for $name {}

        impl From<usize> for $name {
            fn from(value: usize) -> Self {
                Self(value as _)
            }
        }

        impl fmt::Display for $name {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{}", self.0)
            }
        }

        // Defined so that e.g., `0.into()` is possible.
        impl From<i32> for $name {
            fn from(value: i32) -> Self {
                Self(value as _)
            }
        }
    };
}
// TODO(1.0): convert this into a proper trait.
macro_rules! auto_inc_system_id {
    ($name:ident) => {
        impl $name {
            /// The sentinel value for this type.
            /// This will be initialized to a valid ID upon insertion into a system table as a primary key.
            pub const SENTINEL: Self = Self(0);

            /// Check if this ID is the sentinel value.
            pub fn is_sentinel(self) -> bool {
                self == Self::SENTINEL
            }
        }
    };
}

system_id! {
    /// An identifier for a table, unique within a database.
    pub struct TableId(pub u32);
}
auto_inc_system_id!(TableId);

system_id! {
    /// An identifier for a sequence, unique within a database.
    pub struct SequenceId(pub u32);
}
auto_inc_system_id!(SequenceId);

system_id! {
    /// An identifier for an index, unique within a database.
    pub struct IndexId(pub u32);
}
auto_inc_system_id!(IndexId);

system_id! {
    /// An identifier for a constraint, unique within a database.
    pub struct ConstraintId(pub u32);
}
auto_inc_system_id!(ConstraintId);

system_id! {
    /// An identifier for a schedule, unique within a database.
    pub struct ScheduleId(pub u32);
}
auto_inc_system_id!(ScheduleId);

system_id! {
    /// The position of a column within a table.
    ///
    /// A `ColId` does NOT uniquely identify a column within a database!
    /// A pair `(TableId, ColId)` is required for this.
    /// Each table will have columns with `ColId` values ranging from `0` to `n-1`, where `n` is the number of columns in the table.
    /// A table may have at most `u16::MAX` columns.
    pub struct ColId(pub u16);
}
// ColId works differently from other system IDs and is not auto-incremented.