use std::{future::Future, pin::Pin};
use runifold_core::{CancellationToken, EffectRequest, Instant, RunContext, RunError, RunId};
use serde_json::Value;
#[cfg(not(target_arch = "wasm32"))]
pub type EffectFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
#[cfg(target_arch = "wasm32")]
pub type EffectFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
#[derive(Clone, Debug)]
pub struct EffectExecutionContext {
run_id: RunId,
deadline: Option<Instant>,
cancellation: CancellationToken,
}
impl EffectExecutionContext {
pub(crate) fn for_run(run: &RunContext) -> Self {
Self {
run_id: run.run_id(),
deadline: run.deadline(),
cancellation: run.cancellation().child_token(),
}
}
pub const fn run_id(&self) -> RunId {
self.run_id
}
pub const fn deadline(&self) -> Option<Instant> {
self.deadline
}
pub const fn cancellation(&self) -> &CancellationToken {
&self.cancellation
}
}
pub trait EffectHandler: Send + Sync {
fn execute(
&self,
request: &EffectRequest,
context: EffectExecutionContext,
) -> EffectFuture<'_, Result<Value, RunError>>;
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum EffectReconciliation {
Completed(Value),
NotExecuted,
Ambiguous,
}
pub trait EffectReconciler: Send + Sync {
fn reconcile(
&self,
request: &EffectRequest,
context: EffectExecutionContext,
) -> EffectFuture<'_, Result<EffectReconciliation, RunError>>;
}