use async_std::sync::Mutex;
use crate::mediator::{
asynchronous::{
basic::basic::BasicAsyncMediator,
contextaware::{
contextaware::CxAwareAsyncMediator, interface::CxAwareMediatorBuilderInterface,
},
},
builder::{TryBuilderFlow, TryBuilderInternal},
listener::Listener,
synchronous::basic::{basic::BasicMediator, interface::BasicMediatorBuilderInterface},
};
use std::{fmt::Debug, sync::mpsc::channel};
pub struct CxAwareAsyncBuilder<Cx, Ev>
where
Cx: Debug,
Ev: Debug + 'static,
{
mediator: BasicMediator<Ev>,
cx: Option<Cx>,
}
impl<Cx, Ev> TryBuilderInternal<CxAwareAsyncMediator<Cx, Ev>, CxAwareAsyncBuilder<Cx, Ev>>
for CxAwareAsyncMediator<Cx, Ev>
where
Cx: Debug,
Ev: Debug,
{
fn builder() -> CxAwareAsyncBuilder<Cx, Ev> {
CxAwareAsyncBuilder::<Cx, Ev> {
mediator: BasicMediator::<Ev> {
channel: channel(),
listener: vec![],
},
cx: None,
}
}
}
impl<M, Cx, Ev> BasicMediatorBuilderInterface<M, Ev> for CxAwareAsyncBuilder<Cx, Ev>
where
Cx: Debug,
Ev: Debug,
{
fn add_listener(mut self, f: impl Listener<Ev>) -> Self {
self.mediator.listener.push(Box::new(f));
self
}
}
impl<M, Cx, Ev> CxAwareMediatorBuilderInterface<M, Cx, Ev> for CxAwareAsyncBuilder<Cx, Ev>
where
Cx: Debug,
Ev: Debug,
{
fn add_context(mut self, cx: Cx) -> Self
where
Ev: Debug,
{
self.cx = Some(cx);
self
}
}
impl<Cx, Ev> CxAwareAsyncBuilder<Cx, Ev>
where
Cx: Debug,
Ev: Debug,
{
pub fn add_listener(self, f: impl Listener<Ev>) -> Self {
<Self as BasicMediatorBuilderInterface<CxAwareAsyncMediator<Cx, Ev>, Ev>>::add_listener(
self, f,
)
}
pub fn add_context(self, cx: Cx) -> Self {
<Self as CxAwareMediatorBuilderInterface<CxAwareAsyncMediator<Cx, Ev>, Cx, Ev>>::add_context(
self, cx,
)
}
}
#[derive(Debug)]
pub struct NoCxAvailable;
impl<Cx, Ev> TryBuilderFlow<CxAwareAsyncMediator<Cx, Ev>> for CxAwareAsyncBuilder<Cx, Ev>
where
Cx: Debug,
Ev: Debug,
{
type Error = NoCxAvailable;
fn build(self) -> Result<CxAwareAsyncMediator<Cx, Ev>, Self::Error> {
Ok(CxAwareAsyncMediator {
basic: BasicAsyncMediator {
basic: Mutex::new(self.mediator),
},
cx: Mutex::new(self.cx.ok_or(NoCxAvailable)?),
})
}
}