use gatekeep::{Fact, FactId, GatekeepError};
use keepsake::{RelationId, RelationSpec};
use thiserror::Error;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum QueryPresence {
#[default]
Resolve,
Defer,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FactBinding {
pub(crate) fact: FactId,
pub(crate) relation_id: RelationId,
pub(crate) query_presence: QueryPresence,
}
impl FactBinding {
#[must_use]
pub const fn new(fact: FactId, relation_id: RelationId) -> Self {
Self::with_query_presence(fact, relation_id, QueryPresence::Resolve)
}
#[must_use]
pub const fn with_query_presence(
fact: FactId,
relation_id: RelationId,
query_presence: QueryPresence,
) -> Self {
Self {
fact,
relation_id,
query_presence,
}
}
pub fn for_relation_spec<F, R>() -> Result<Self, FactBindingError>
where
F: Fact,
R: RelationSpec,
{
Self::for_relation_spec_with_query_presence::<F, R>(QueryPresence::Resolve)
}
pub fn resolve_relation<F, R>() -> Result<Self, FactBindingError>
where
F: Fact,
R: RelationSpec,
{
Self::for_relation_spec_with_query_presence::<F, R>(QueryPresence::Resolve)
}
pub fn defer_relation<F, R>() -> Result<Self, FactBindingError>
where
F: Fact,
R: RelationSpec,
{
Self::for_relation_spec_with_query_presence::<F, R>(QueryPresence::Defer)
}
pub fn for_relation_spec_with_query_presence<F, R>(
query_presence: QueryPresence,
) -> Result<Self, FactBindingError>
where
F: Fact,
R: RelationSpec,
{
Ok(Self::with_query_presence(
F::ID.to_owned_id()?,
R::ID,
query_presence,
))
}
#[must_use]
pub const fn fact(&self) -> &FactId {
&self.fact
}
#[must_use]
pub const fn relation_id(&self) -> RelationId {
self.relation_id
}
#[must_use]
pub const fn query_presence(&self) -> QueryPresence {
self.query_presence
}
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum FactBindingError {
#[error(transparent)]
Gatekeep(#[from] GatekeepError),
}