use std::marker::PhantomData;
use super::{DomainError, MAX_GRAPH_CHANGES, NodeId, RelId};
type Scope<'batch> = PhantomData<fn(&'batch ()) -> &'batch ()>;
#[derive(Clone, Copy, Debug)]
pub struct LocalRefs<'batch>(Scope<'batch>);
pub fn with_local_refs<R>(build: impl for<'batch> FnOnce(LocalRefs<'batch>) -> R) -> R {
build(LocalRefs(PhantomData))
}
macro_rules! local_ref {
($name:ident, $method:ident, $doc:literal) => {
#[doc = $doc]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct $name<'batch> {
index: u32,
scope: Scope<'batch>,
}
impl $name<'_> {
#[must_use]
pub const fn index(self) -> u32 {
self.index
}
}
impl<'batch> LocalRefs<'batch> {
#[doc = $doc]
pub fn $method(self, index: usize) -> Result<$name<'batch>, DomainError> {
if index >= MAX_GRAPH_CHANGES {
return Err(DomainError::LocalReferenceOutOfRange);
}
let index =
u32::try_from(index).map_err(|_| DomainError::LocalReferenceOutOfRange)?;
Ok($name {
index,
scope: self.0,
})
}
}
};
}
local_ref!(
LocalNodeRef,
node,
"A node creation slot, confined to its batch scope."
);
local_ref!(
LocalRelRef,
relationship,
"A relationship creation slot, confined to its batch scope."
);
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NodeRef<'batch> {
Existing(NodeId),
Local(LocalNodeRef<'batch>),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RelRef<'batch> {
Existing(RelId),
Local(LocalRelRef<'batch>),
}