use std::num::NonZeroU32;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(in crate::db) struct ConstraintId(NonZeroU32);
impl ConstraintId {
#[must_use]
pub(in crate::db) const fn new(raw: u32) -> Option<Self> {
match NonZeroU32::new(raw) {
Some(raw) => Some(Self(raw)),
None => None,
}
}
#[must_use]
pub(in crate::db) const fn get(self) -> u32 {
self.0.get()
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub(in crate::db) struct ConstraintIdAllocator {
high_water: Option<ConstraintId>,
}
impl ConstraintIdAllocator {
#[must_use]
pub(in crate::db) const fn new(high_water: u32) -> Self {
Self {
high_water: ConstraintId::new(high_water),
}
}
#[must_use]
pub(in crate::db) const fn high_water(self) -> u32 {
match self.high_water {
Some(high_water) => high_water.get(),
None => 0,
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(in crate::db) struct SchemaIndexId(NonZeroU32);
impl SchemaIndexId {
#[must_use]
pub(in crate::db) const fn new(raw: u32) -> Option<Self> {
match NonZeroU32::new(raw) {
Some(raw) => Some(Self(raw)),
None => None,
}
}
#[must_use]
pub(in crate::db) const fn get(self) -> u32 {
self.0.get()
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(in crate::db) struct RelationId(NonZeroU32);
impl RelationId {
#[must_use]
pub(in crate::db) const fn new(raw: u32) -> Option<Self> {
match NonZeroU32::new(raw) {
Some(raw) => Some(Self(raw)),
None => None,
}
}
#[must_use]
pub(in crate::db) const fn get(self) -> u32 {
self.0.get()
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(in crate::db) struct FieldId(u32);
impl FieldId {
#[must_use]
pub(in crate::db) const fn new(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub(in crate::db) const fn get(self) -> u32 {
self.0
}
#[must_use]
pub(in crate::db) fn from_initial_slot(slot: usize) -> Self {
let next = u32::try_from(slot)
.expect("schema identity invariant")
.checked_add(1)
.expect("schema identity invariant");
Self(next)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn constraint_allocator_preserves_reserved_high_water_identity() {
let empty = ConstraintIdAllocator::default();
let reserved = ConstraintIdAllocator::new(7);
assert_eq!(empty.high_water(), 0);
assert_eq!(reserved.high_water(), 7);
}
#[test]
fn logical_structural_ids_reject_zero() {
assert_eq!(SchemaIndexId::new(0), None);
assert_eq!(RelationId::new(0), None);
}
}