61 lines
1.6 KiB
Rust
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"));
|
|
}
|
|
}
|