use core::marker::PhantomData;
#[derive(Clone, Copy)]
pub(crate) struct Brand<'brand> {
_marker: PhantomData<&'brand mut &'brand ()>,
}
#[cfg(test)]
impl<'brand> Brand<'brand> {
#[inline]
const fn new() -> Self {
Self {
_marker: PhantomData,
}
}
#[inline]
pub(crate) fn guard(&self) -> Guard<'brand> {
Guard::new()
}
}
#[derive(Clone, Copy)]
pub(crate) struct Guard<'brand> {
_marker: PhantomData<&'brand mut &'brand ()>,
}
impl<'brand> Guard<'brand> {
#[inline]
pub(crate) const fn new() -> Self {
Self {
_marker: PhantomData,
}
}
}
#[cfg(test)]
pub(crate) fn with_brand<R>(f: impl for<'brand> FnOnce(Brand<'brand>) -> R) -> R {
struct Wrapper<F>(F);
impl<F> Wrapper<F> {
#[inline]
fn run<R>(self) -> R
where
F: for<'brand> FnOnce(Brand<'brand>) -> R,
{
fn call<'brand, R>(f: impl FnOnce(Brand<'brand>) -> R) -> R {
f(Brand::new())
}
call(self.0)
}
}
Wrapper(f).run()
}
#[cfg(test)]
mod tests {
use super::with_brand;
#[test]
fn brands_are_unique() {
with_brand(|brand_a| {
let guard_a = brand_a.guard();
with_brand(|brand_b| {
let guard_b = brand_b.guard();
let _ = guard_a;
let _ = guard_b;
});
});
}
}