use std::sync::Arc;
use datafusion::arrow::record_batch::RecordBatch;
use smol_str::SmolStr;
use crate::errors::FnError;
pub trait TriggerPlugin: Send + Sync {
fn subscription(&self) -> &TriggerSubscription;
fn fire(
&self,
ctx: TriggerContext<'_>,
events: &MutationBatch,
) -> Result<TriggerOutcome, FnError>;
fn on_deferred(
&self,
ctx: TriggerContext<'_>,
events: &MutationBatch,
_payload: &str,
) -> Result<TriggerOutcome, FnError> {
self.fire(ctx, events)
}
}
#[derive(Clone, Debug)]
pub struct TriggerSubscription {
pub phase: TriggerPhase,
pub events: TriggerEventMask,
pub labels: Option<Vec<SmolStr>>,
pub edge_types: Option<Vec<SmolStr>>,
pub properties: Option<Vec<SmolStr>>,
pub predicate_source: Option<String>,
pub fire_mode: FireMode,
pub docs: String,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum TriggerPhase {
BeforeMutation,
AfterMutation,
BeforeCommit,
AfterCommit,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct TriggerEventMask(pub u32);
impl TriggerEventMask {
pub const NODE_CREATE: Self = Self(1 << 0);
pub const NODE_UPDATE: Self = Self(1 << 1);
pub const NODE_DELETE: Self = Self(1 << 2);
pub const EDGE_CREATE: Self = Self(1 << 3);
pub const EDGE_UPDATE: Self = Self(1 << 4);
pub const EDGE_DELETE: Self = Self(1 << 5);
pub const PROPERTY_CHANGE: Self = Self(1 << 6);
pub const LABEL_ADDED: Self = Self(1 << 7);
pub const LABEL_REMOVED: Self = Self(1 << 8);
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
#[must_use]
pub const fn contains(self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum FireMode {
Synchronous,
Async,
EventualConsistency,
}
#[derive(Debug)]
#[non_exhaustive]
pub enum TriggerOutcome {
Continue,
Reject {
reason: String,
},
Defer {
until: TriggerDeferral,
},
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct TriggerDeferral {
pub payload: String,
pub delay: Option<std::time::Duration>,
}
impl TriggerDeferral {
#[must_use]
pub fn from_payload(payload: impl Into<String>) -> Self {
Self {
payload: payload.into(),
delay: None,
}
}
#[must_use]
pub fn after(payload: impl Into<String>, delay: std::time::Duration) -> Self {
Self {
payload: payload.into(),
delay: Some(delay),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct TriggerContext<'a> {
pub session_id: &'a str,
pub tx_id: u64,
}
impl<'a> TriggerContext<'a> {
#[must_use]
pub fn new(session_id: &'a str, tx_id: u64) -> Self {
Self { session_id, tx_id }
}
}
#[derive(Clone, Debug)]
pub struct MutationBatch {
pub events: Arc<RecordBatch>,
}