use crate::{CapSet, Imm};
#[derive(Hash, Clone, Copy, PartialEq, Eq)]
pub struct ImmId {
id: u64,
}
pub fn imm_id<T: std::hash::Hash>(val: T) -> ImmId {
ImmId::new(val)
}
impl ImmId {
pub fn new(source: impl std::hash::Hash) -> Self {
Self {
id: ahash::RandomState::with_seeds(1, 2, 3, 4).hash_one(source),
}
}
pub fn with(self, child: impl std::hash::Hash) -> Self {
use std::hash::{BuildHasher as _, Hasher as _};
let mut hasher = ahash::RandomState::with_seeds(1, 2, 3, 4).build_hasher();
hasher.write_u64(self.id);
child.hash(&mut hasher);
Self {
id: hasher.finish(),
}
}
pub fn raw(&self) -> u64 {
self.id
}
}
impl<A> FromIterator<A> for ImmId
where
A: std::hash::Hash,
{
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
use std::hash::{BuildHasher as _, Hasher as _};
let mut hasher = ahash::RandomState::with_seeds(1, 2, 3, 4).build_hasher();
for item in iter {
item.hash(&mut hasher);
}
Self {
id: hasher.finish(),
}
}
}
pub enum ImmIdBuilder {
Auto,
Hierarchy(ImmId),
Unique(ImmId),
}
impl ImmIdBuilder {
pub(super) fn resolve<Caps: CapSet>(self, sui: &mut Imm<Caps>) -> ImmId {
match self {
ImmIdBuilder::Auto => {
const AUTO: u32 = 295847291;
let id = sui
.current
.id
.with((AUTO, sui.current.id_pref, sui.current.auto_id_idx));
sui.current.auto_id_idx += 1;
id
}
ImmIdBuilder::Hierarchy(sui_id) => {
const HIERARCHY: u32 = 958472831;
sui.current
.id
.with((HIERARCHY, sui.current.id_pref, sui_id))
}
ImmIdBuilder::Unique(sui_id) => sui_id,
}
}
}