use std::fmt::{Debug, Display};
use std::future::Future;
use std::sync::Arc;
use crate::proto;
pub trait FacilitatorContract {
type VerifyRequest;
type VerifyResponse;
type SettleRequest;
type SettleResponse;
type SupportedResponse;
}
pub struct ProtoContract;
impl FacilitatorContract for ProtoContract {
type VerifyRequest = proto::VerifyRequest;
type VerifyResponse = proto::VerifyResponse;
type SettleRequest = proto::SettleRequest;
type SettleResponse = proto::SettleResponse;
type SupportedResponse = proto::SupportedResponse;
}
pub trait Facilitator<C: FacilitatorContract = ProtoContract> {
type Error: Debug + Display;
fn verify(
&self,
request: &C::VerifyRequest,
) -> impl Future<Output = Result<C::VerifyResponse, Self::Error>> + Send;
fn settle(
&self,
request: &C::SettleRequest,
) -> impl Future<Output = Result<C::SettleResponse, Self::Error>> + Send;
#[allow(dead_code)] fn supported(&self) -> impl Future<Output = Result<C::SupportedResponse, Self::Error>> + Send;
}
impl<C, T> Facilitator<C> for Arc<T>
where
C: FacilitatorContract,
T: Facilitator<C>,
{
type Error = T::Error;
fn verify(
&self,
request: &C::VerifyRequest,
) -> impl Future<Output = Result<C::VerifyResponse, Self::Error>> + Send {
self.as_ref().verify(request)
}
fn settle(
&self,
request: &C::SettleRequest,
) -> impl Future<Output = Result<C::SettleResponse, Self::Error>> + Send {
self.as_ref().settle(request)
}
fn supported(&self) -> impl Future<Output = Result<C::SupportedResponse, Self::Error>> + Send {
self.as_ref().supported()
}
}