use crate::errors::EventHexError;
use async_trait::async_trait;
use futures::future::BoxFuture;
use std::any::Any;
pub type ErasedResult = Box<dyn Any + Send>;
#[async_trait]
pub trait EventTransactionContext: Send {
fn as_any_mut(&mut self) -> &mut dyn Any;
}
pub type EventTransactionHandler = Box<dyn for<'a> FnOnce(&'a mut dyn EventTransactionContext) -> BoxFuture<'a, Result<ErasedResult, EventHexError>> + Send>;
#[async_trait]
pub trait EventTransactionManager: Send + Sync {
async fn run_transaction(&self, handler: EventTransactionHandler) -> Result<ErasedResult, EventHexError>;
}
impl dyn EventTransactionManager {
pub async fn run<T, F>(&self, f: F) -> Result<T, EventHexError>
where
T: Any + Send + 'static,
F: FnOnce(&mut dyn EventTransactionContext) -> BoxFuture<'_, Result<T, EventHexError>> + Send + 'static,
{
let handler: EventTransactionHandler = Box::new(|ctx| {
Box::pin(async move {
let res = f(ctx).await?;
let erased: ErasedResult = Box::new(res);
Ok(erased)
})
});
let erased_result = self.run_transaction(handler).await?;
erased_result
.downcast::<T>()
.map(|boxed_t| *boxed_t)
.map_err(|_| EventHexError::DownCastError("Downcast failed in transaction".into()))
}
}