use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
pub use crate::error::FacilitatorError;
use crate::wire::{
SettleRequest, SettleResponse, SupportedResponse, VerifyRequest, VerifyResponse,
};
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
pub trait Facilitator: Send + Sync {
fn verify(
&self,
request: VerifyRequest,
) -> impl Future<Output = Result<VerifyResponse, FacilitatorError>> + Send;
fn settle(
&self,
request: SettleRequest,
) -> impl Future<Output = Result<SettleResponse, FacilitatorError>> + Send;
fn supported(&self)
-> impl Future<Output = Result<SupportedResponse, FacilitatorError>> + Send;
}
pub trait DynFacilitator: Send + Sync {
fn verify(
&self,
request: VerifyRequest,
) -> BoxFuture<'_, Result<VerifyResponse, FacilitatorError>>;
fn settle(
&self,
request: SettleRequest,
) -> BoxFuture<'_, Result<SettleResponse, FacilitatorError>>;
fn supported(&self) -> BoxFuture<'_, Result<SupportedResponse, FacilitatorError>>;
}
impl<T> DynFacilitator for T
where
T: Facilitator + ?Sized,
{
fn verify(
&self,
request: VerifyRequest,
) -> BoxFuture<'_, Result<VerifyResponse, FacilitatorError>> {
Box::pin(<Self as Facilitator>::verify(self, request))
}
fn settle(
&self,
request: SettleRequest,
) -> BoxFuture<'_, Result<SettleResponse, FacilitatorError>> {
Box::pin(<Self as Facilitator>::settle(self, request))
}
fn supported(&self) -> BoxFuture<'_, Result<SupportedResponse, FacilitatorError>> {
Box::pin(<Self as Facilitator>::supported(self))
}
}
impl<T: Facilitator> Facilitator for Arc<T> {
async fn verify(&self, request: VerifyRequest) -> Result<VerifyResponse, FacilitatorError> {
self.as_ref().verify(request).await
}
async fn settle(&self, request: SettleRequest) -> Result<SettleResponse, FacilitatorError> {
self.as_ref().settle(request).await
}
async fn supported(&self) -> Result<SupportedResponse, FacilitatorError> {
self.as_ref().supported().await
}
}
impl<T: Facilitator> Facilitator for Box<T> {
async fn verify(&self, request: VerifyRequest) -> Result<VerifyResponse, FacilitatorError> {
self.as_ref().verify(request).await
}
async fn settle(&self, request: SettleRequest) -> Result<SettleResponse, FacilitatorError> {
self.as_ref().settle(request).await
}
async fn supported(&self) -> Result<SupportedResponse, FacilitatorError> {
self.as_ref().supported().await
}
}
impl Facilitator for Box<dyn DynFacilitator> {
async fn verify(&self, request: VerifyRequest) -> Result<VerifyResponse, FacilitatorError> {
DynFacilitator::verify(self.as_ref(), request).await
}
async fn settle(&self, request: SettleRequest) -> Result<SettleResponse, FacilitatorError> {
DynFacilitator::settle(self.as_ref(), request).await
}
async fn supported(&self) -> Result<SupportedResponse, FacilitatorError> {
DynFacilitator::supported(self.as_ref()).await
}
}
impl Facilitator for Arc<dyn DynFacilitator> {
async fn verify(&self, request: VerifyRequest) -> Result<VerifyResponse, FacilitatorError> {
DynFacilitator::verify(self.as_ref(), request).await
}
async fn settle(&self, request: SettleRequest) -> Result<SettleResponse, FacilitatorError> {
DynFacilitator::settle(self.as_ref(), request).await
}
async fn supported(&self) -> Result<SupportedResponse, FacilitatorError> {
DynFacilitator::supported(self.as_ref()).await
}
}