67 lines
1.5 KiB
Rust
67 lines
1.5 KiB
Rust
/// intentionally does not implement copy or clone
|
|
/// which should make it harder to misuse;
|
|
/// the idea is to generally try to guarantee all IDs
|
|
/// point to something valid, although duplicate
|
|
/// gets around this if needed
|
|
#[derive(Eq, Hash, PartialEq, Debug)]
|
|
pub struct Id(u64);
|
|
|
|
#[derive(Default)]
|
|
pub struct IdTracker {
|
|
free: Vec<Id>,
|
|
cur: u64,
|
|
}
|
|
|
|
impl IdTracker {
|
|
#[allow(clippy::should_implement_trait)]
|
|
pub fn next(&mut self) -> Id {
|
|
if let Some(id) = self.free.pop() {
|
|
return id;
|
|
}
|
|
let id = Id(self.cur);
|
|
self.cur += 1;
|
|
id
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn free(&mut self, id: Id) {
|
|
self.free.push(id);
|
|
}
|
|
}
|
|
|
|
impl Id {
|
|
/// this must be used carefully to make sure
|
|
/// all IDs are still valid references;
|
|
/// named weirdly to indicate this.
|
|
/// generally should not be used in "user" code
|
|
pub fn duplicate(&self) -> Self {
|
|
Self(self.0)
|
|
}
|
|
|
|
/// this must be used carefully to make sure
|
|
/// all IDs are still valid references.
|
|
/// generally should not be used in "user" code
|
|
pub fn copyable(&self) -> CopyId {
|
|
CopyId(self.0)
|
|
}
|
|
}
|
|
|
|
#[derive(Eq, Hash, PartialEq, Debug, Clone, Copy)]
|
|
pub struct CopyId(u64);
|
|
|
|
impl CopyId {
|
|
pub fn id(&self) -> Id {
|
|
Id(self.0)
|
|
}
|
|
}
|
|
|
|
pub trait IdUtil {
|
|
fn duplicate(&self) -> Self;
|
|
}
|
|
|
|
impl IdUtil for Option<Id> {
|
|
fn duplicate(&self) -> Self {
|
|
self.as_ref().map(|i| i.duplicate())
|
|
}
|
|
}
|