use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct NodeId(pub u64);
impl NodeId {
#[inline]
pub fn new() -> Self {
Self(NODE_COUNTER.fetch_add(1, Ordering::Relaxed))
}
#[inline]
pub const fn from_raw(value: u64) -> Self {
Self(value)
}
#[inline]
pub fn from_ptr(ptr: usize) -> Self {
Self(ptr as u64)
}
#[inline]
pub const fn as_u64(&self) -> u64 {
self.0
}
#[inline]
pub const fn is_valid(&self) -> bool {
self.0 > 0
}
}
impl Default for NodeId {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for NodeId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
pub const VIRTUAL_PTR_BASE: usize = 0x10000000000;
#[inline]
pub const fn is_virtual_pointer(ptr: usize) -> bool {
ptr >= VIRTUAL_PTR_BASE
}
static NODE_COUNTER: AtomicU64 = AtomicU64::new(1);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_id_uniqueness() {
let id1 = NodeId::new();
let id2 = NodeId::new();
assert_ne!(id1, id2);
}
#[test]
fn test_node_id_validity() {
let id = NodeId::new();
assert!(id.is_valid());
let invalid_id = NodeId::from_raw(0);
assert!(!invalid_id.is_valid());
}
#[test]
fn test_node_id_from_raw() {
let value = 42u64;
let id = NodeId::from_raw(value);
assert_eq!(id.as_u64(), value);
}
#[test]
fn test_node_id_ord() {
let id1 = NodeId::new();
let id2 = NodeId::new();
assert!(id1 < id2);
}
}