mod guard;
use crate::Broker;
use crate::runtime::middleware::Identity;
use crate::runtime::router::{Router, RouterMount, forms};
use super::scope::BrokerScope;
pub use guard::{Mounting, MountingSlots, ScopeCommit};
pub(crate) type ScopeRouter<B, C, Pipeline> = Router<B, (), C, Identity, Pipeline>;
type ScopeChain<Form, B, C, Pipeline, Def> =
<Form as RouterMount<ScopeRouter<B, C, Pipeline>, Def>>::Out;
#[doc(hidden)]
pub trait IncludeMount<'s, B: Broker, Layers, C, State, Pipeline, Def> {
type Out;
fn begin(def: Def, scope: &'s mut BrokerScope<B, Layers, C, State, Pipeline>) -> Self::Out;
}
macro_rules! scope_mount {
($($form:ty),+ $(,)?) => {$(
impl<'s, B, Layers, C, State, Pipeline, Def>
IncludeMount<'s, B, Layers, C, State, Pipeline, Def> for $form
where
B: Broker + 'static,
C: Clone + 's,
Layers: 's,
State: 's,
Pipeline: Clone + 's,
Self: RouterMount<ScopeRouter<B, C, Pipeline>, Def>,
ScopeChain<Self, B, C, Pipeline, Def>: ScopeCommit<B, Layers, C, State, Pipeline>,
{
type Out = Mounting<
's,
B,
Layers,
C,
State,
Pipeline,
ScopeChain<Self, B, C, Pipeline, Def>,
>;
fn begin(
def: Def,
scope: &'s mut BrokerScope<B, Layers, C, State, Pipeline>,
) -> Self::Out {
let router = Router::for_scope(scope.codec.clone(), scope.pipeline.clone());
Mounting::new(<Self as RouterMount<_, Def>>::begin(def, router), scope)
}
}
)+};
}
scope_mount! {
forms::Publishing,
forms::RawReply,
forms::BatchPublishing,
}
macro_rules! scope_mount_slots {
($($form:ty),+ $(,)?) => {$(
impl<'s, B, Layers, C, State, Pipeline, Def>
IncludeMount<'s, B, Layers, C, State, Pipeline, Def> for $form
where
B: Broker + 'static,
C: Clone + 's,
Layers: 's,
State: 's,
Pipeline: Clone + 's,
Self: RouterMount<ScopeRouter<B, C, Pipeline>, Def>,
{
type Out = MountingSlots<
's,
B,
Layers,
C,
State,
Pipeline,
ScopeChain<Self, B, C, Pipeline, Def>,
>;
fn begin(
def: Def,
scope: &'s mut BrokerScope<B, Layers, C, State, Pipeline>,
) -> Self::Out {
let router = Router::for_scope(scope.codec.clone(), scope.pipeline.clone());
MountingSlots::new(<Self as RouterMount<_, Def>>::begin(def, router), scope)
}
}
)+};
}
scope_mount_slots! {
forms::Out,
forms::BatchOut,
forms::PublishingOut,
forms::RawReplyOut,
forms::BatchPublishingOut,
}
macro_rules! eager_mount {
($($form:ty),+ $(,)?) => {$(
impl<'s, B, Layers, C, State, Pipeline, Def>
IncludeMount<'s, B, Layers, C, State, Pipeline, Def> for $form
where
B: Broker + 'static,
C: Clone + 's,
Layers: 's,
State: 's,
Pipeline: Clone + 's,
Self: RouterMount<ScopeRouter<B, C, Pipeline>, Def>,
ScopeChain<Self, B, C, Pipeline, Def>: ScopeCommit<B, Layers, C, State, Pipeline>,
{
type Out = Mounting<
's,
B,
Layers,
C,
State,
Pipeline,
ScopeChain<Self, B, C, Pipeline, Def>,
>;
fn begin(
def: Def,
scope: &'s mut BrokerScope<B, Layers, C, State, Pipeline>,
) -> Self::Out {
let router = Router::for_scope(scope.codec.clone(), scope.pipeline.clone());
Mounting::new(<Self as RouterMount<_, Def>>::begin(def, router), scope)
}
}
)+};
}
eager_mount! {
forms::Subscribing,
forms::RawSubscribing,
forms::Batch,
forms::RawBatch,
}
impl<B: Broker + 'static, Layers, C, State, Pipeline> BrokerScope<B, Layers, C, State, Pipeline> {
pub fn include<'s, D>(
&'s mut self,
def: D,
) -> <D::Form as IncludeMount<'s, B, Layers, C, State, Pipeline, D::Settings>>::Out
where
D: crate::runtime::Declared,
D::Form: IncludeMount<'s, B, Layers, C, State, Pipeline, D::Settings>,
{
<D::Form as IncludeMount<'s, B, Layers, C, State, Pipeline, D::Settings>>::begin(
def.declare(),
self,
)
}
}