Skip to main content

oxgraph_db/
id.rs

1//! Canonical database identity newtypes.
2
3use std::fmt;
4
5use serde::{Deserialize, Serialize};
6
7use crate::error::IdFamily;
8
9/// Declares one canonical `u64` identifier newtype.
10macro_rules! id_newtype {
11    ($name:ident, $doc:literal) => {
12        #[doc = $doc]
13        ///
14        /// # Performance
15        ///
16        /// Copying, comparing, ordering, and hashing are `O(1)`.
17        #[derive(
18            Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize,
19        )]
20        #[repr(transparent)]
21        pub struct $name(u64);
22
23        impl $name {
24            /// Creates an identifier from a raw canonical value.
25            ///
26            /// # Performance
27            ///
28            /// This function is `O(1)`.
29            #[must_use]
30            pub const fn new(value: u64) -> Self {
31                Self(value)
32            }
33
34            /// Returns the raw canonical value.
35            ///
36            /// # Performance
37            ///
38            /// This function is `O(1)`.
39            #[must_use]
40            pub const fn get(self) -> u64 {
41                self.0
42            }
43
44            /// Returns the next identifier if it fits.
45            ///
46            /// # Performance
47            ///
48            /// This function is `O(1)`.
49            #[must_use]
50            pub const fn checked_next(self) -> Option<Self> {
51                match self.0.checked_add(1) {
52                    Some(value) => Some(Self(value)),
53                    None => None,
54                }
55            }
56        }
57
58        impl fmt::Display for $name {
59            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
60                write!(formatter, "{}", self.0)
61            }
62        }
63    };
64}
65
66/// Wires one canonical id newtype to its [`IdFamily`] discriminant, so error
67/// constructors can take any family id generically.
68macro_rules! id_family {
69    ($name:ident, $family:ident) => {
70        impl From<$name> for (IdFamily, u64) {
71            fn from(id: $name) -> Self {
72                (IdFamily::$family, id.get())
73            }
74        }
75    };
76}
77
78id_newtype!(ElementId, "Stable canonical element identifier.");
79id_newtype!(RelationId, "Stable canonical relation identifier.");
80id_newtype!(IncidenceId, "Stable canonical incidence identifier.");
81id_newtype!(RoleId, "Stable canonical structural role identifier.");
82id_newtype!(LabelId, "Stable catalog label identifier.");
83id_newtype!(RelationTypeId, "Stable catalog relation-type identifier.");
84id_newtype!(PropertyKeyId, "Stable catalog property-key identifier.");
85id_newtype!(ProjectionId, "Stable catalog projection identifier.");
86id_newtype!(IndexId, "Stable catalog index identifier.");
87id_family!(ElementId, Element);
88id_family!(RelationId, Relation);
89id_family!(IncidenceId, Incidence);
90id_family!(RoleId, Role);
91id_family!(LabelId, Label);
92id_family!(RelationTypeId, RelationType);
93id_family!(PropertyKeyId, PropertyKey);
94id_family!(ProjectionId, Projection);
95id_family!(IndexId, Index);
96
97id_newtype!(CommitSeq, "Monotonic committed transaction sequence.");
98id_newtype!(TransactionId, "Monotonic writer transaction identifier.");
99id_newtype!(
100    CheckpointGeneration,
101    "Immutable checkpoint generation identifier."
102);