use crate::shared_kernel::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 TransactionContext: Send {
fn as_any_mut(&mut self) -> &mut dyn Any;
}
pub type TransactionHandler = Box<dyn for<'a> FnOnce(&'a mut dyn TransactionContext) -> BoxFuture<'a, Result<ErasedResult, EventHexError>> + Send>;
#[async_trait]
pub trait TransactionManager: Send + Sync {
async fn run_transaction(&self, handler: TransactionHandler) -> Result<ErasedResult, EventHexError>;
}
impl dyn TransactionManager {
pub async fn run<T, F>(&self, f: F) -> Result<T, EventHexError>
where
T: Any + Send + 'static,
F: FnOnce(&mut dyn TransactionContext) -> BoxFuture<'_, Result<T, EventHexError>> + Send + 'static,
{
let handler: TransactionHandler = 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()))
}
}