use crate::codec::{Codec, CodecName};
use crate::erasure::reactant::{ErrorReactantErased, ReactantErased, ReactantRawErased};
use crate::payload::{Payload, PayloadRaw};
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ReactantError {
#[error("Reactant execution failed: {0}")]
Execution(String),
#[error(transparent)]
Other(#[from] Box<dyn std::error::Error + Send + Sync>),
}
pub trait Reactant<T, C>
where
C: Codec<T> + CodecName + Send + Sync + 'static,
T: Send + Sync + 'static,
Self: Send + Sync,
{
fn react(
&self,
payload: Arc<Payload<T, C>>,
) -> Pin<Box<dyn Future<Output = Result<(), ReactantError>> + Send + 'static>>;
fn erase(self: Box<Self>) -> Arc<dyn ReactantErased + Send + Sync + 'static>;
fn new_erased(self) -> Arc<dyn ReactantErased + Send + Sync + 'static>
where
Self: Sized + 'static,
{
Box::new(self).erase()
}
}
pub trait ReactantRaw<T, C>
where
C: Codec<T> + CodecName + Send + Sync + 'static,
T: Send + Sync + 'static,
Self: Send + Sync,
{
fn react(
&self,
payload: Arc<PayloadRaw<T, C>>,
) -> Pin<Box<dyn Future<Output = Result<(), ReactantError>> + Send + 'static>>;
fn erase_raw(self: Box<Self>) -> Arc<dyn ReactantRawErased + Send + Sync + 'static>;
fn new_erased_raw(self) -> Arc<dyn ReactantRawErased + Send + Sync + 'static>
where
Self: Sized + 'static,
{
Box::new(self).erase_raw()
}
}
pub trait ErrorReactant<T, C>: Send + Sync
where
C: Codec<T> + CodecName + Send + Sync + 'static,
T: Send + Sync + 'static,
{
fn react_error(
&self,
error: Arc<ReactantError>,
payload: Arc<Payload<T, C>>,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
fn erase_error(self: Box<Self>) -> Arc<dyn ErrorReactantErased + Send + Sync + 'static>;
fn new_erased_error(self) -> Arc<dyn ErrorReactantErased + Send + Sync + 'static>
where
Self: Sized + 'static,
{
Box::new(self).erase_error()
}
}