use std::sync::atomic::{AtomicUsize, Ordering};
use std::cmp::PartialOrd;
use std::cmp::Ordering as CmpOrdering;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum IdKind {
HookId,
ThreadId,
#[doc(hidden)] __NonExaustiveMatch,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct UniqueId {
id: usize,
kind: IdKind,
}
impl PartialOrd for UniqueId {
fn partial_cmp(&self, other: &Self) -> Option<CmpOrdering> {
if self.kind == other.kind {
self.id.partial_cmp(&other.id)
} else {
None
}
}
}
#[derive(Debug)]
pub struct State {
counter: AtomicUsize,
}
impl State {
pub fn new() -> Self {
State {
counter: AtomicUsize::new(0),
}
}
pub fn next_id(&self, kind: IdKind) -> UniqueId {
UniqueId {
id: self.counter.fetch_add(1, Ordering::SeqCst),
kind: kind,
}
}
}
#[cfg(test)]
mod tests {
use super::{IdKind, State};
#[test]
fn test_next_id() {
let state = State::new();
let id1 = state.next_id(IdKind::HookId);
let id2 = state.next_id(IdKind::HookId);
let id3 = state.next_id(IdKind::ThreadId);
assert!(id1 < id2);
assert!(id1 == id1);
assert!(id1 != id2);
assert!(id1 != id3);
}
}