61 lines
1.6 KiB
Rust

macro_rules! define_id {
($name:ident) => {
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)]
pub struct $name(pub u32);
impl $name {
pub const NONE: $name = $name(u32::MAX);
#[inline]
pub const fn as_u32(self) -> u32 { self.0 }
#[inline]
pub fn is_none(self) -> bool {
self == $name::NONE
}
}
impl From<u32> for $name {
#[inline]
fn from(value: u32) -> Self { Self(value) }
}
impl From<$name> for u32 {
#[inline]
fn from(value: $name) -> Self { value.0 }
}
};
}
define_id!(FileId);
define_id!(NodeId);
define_id!(NameId);
define_id!(SymbolId);
define_id!(TypeId);
define_id!(ModuleId);
define_id!(ProjectId);
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
use std::mem::size_of;
#[test]
fn ids_are_repr_transparent_and_hashable() {
assert_eq!(size_of::<FileId>(), 4);
assert_eq!(size_of::<NodeId>(), 4);
assert_eq!(size_of::<NameId>(), 4);
assert_eq!(size_of::<SymbolId>(), 4);
assert_eq!(size_of::<TypeId>(), 4);
assert_eq!(size_of::<ModuleId>(), 4);
assert_eq!(size_of::<ProjectId>(), 4);
// Hash/Eq usage
let mut m: HashMap<SymbolId, &str> = HashMap::new();
m.insert(SymbolId(1), "one");
assert_eq!(m.get(&SymbolId(1)).copied(), Some("one"));
}
}