1use std::borrow::Cow;
15use std::fmt;
16use std::num::NonZeroU32;
17
18use crate::Broker;
19
20use crate::runtime::app::scope::BrokerScope;
21use crate::runtime::middleware::BlanketLayer;
22use crate::runtime::publish::{PublishIdentity, PublishPipeline};
23use crate::runtime::retry::{
24 Absent, CapOpen, DeadLetterOpen, DeclareCap, DeclareDeadLetter, DeclareMount, DestinationLast,
25 DestinationOpen, Present, Retry, RetryOpen, RouteDeclaring, RoutePosition,
26};
27use crate::runtime::router::{
28 MapPublisher, Router, RouterBroker, RouterCommit, RouterDef, RouterWith,
29};
30use crate::runtime::slot::{
31 AdmitsAt, BatchTransformLast, CodecLast, MapPolicyLast, NamedStep, OutPosition, Reply,
32 ReplyLast, ReplyStep, TransactionalLast, TransformLast,
33};
34
35#[doc(hidden)]
37pub trait ScopeCommit<B: Broker, Layers, C, State, Pipeline>: Sized {
38 fn commit_into(self, scope: &mut BrokerScope<B, Layers, C, State, Pipeline>);
39}
40
41impl<B, Layers, C, State, Pipeline, Routes, RC, RL, RP> ScopeCommit<B, Layers, C, State, Pipeline>
44 for Router<B, Routes, RC, RL, RP>
45where
46 B: Broker + 'static,
47 Routes: RouterDef<B, State, RP>,
48 RL: BlanketLayer + Clone + Send + Sync + 'static,
49 Layers: BlanketLayer + Clone + Send + Sync + 'static,
50 Pipeline: PublishPipeline + Clone + Send + 'static,
51 State: Send + Sync + 'static,
52{
53 fn commit_into(self, scope: &mut BrokerScope<B, Layers, C, State, Pipeline>) {
54 RouterDef::mount(
57 self,
58 &scope.global,
59 &scope.pipeline,
60 &PublishIdentity,
61 &mut scope.sink,
62 );
63 }
64}
65
66impl<B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last>
68 ScopeCommit<B, Layers, C, State, Pipeline> for RouterWith<Mount, R, Def, Attach, Last>
69where
70 B: Broker + 'static,
71 Attach: RouterCommit<Mount, R, Def>,
72 Attach::Out: ScopeCommit<B, Layers, C, State, Pipeline>,
73{
74 fn commit_into(self, scope: &mut BrokerScope<B, Layers, C, State, Pipeline>) {
75 self.commit_chain().commit_into(scope);
78 }
79}
80
81pub struct Mounting<'s, B, Layers, C, State, Pipeline, Chain>
91where
92 B: Broker + 'static,
93 Chain: ScopeCommit<B, Layers, C, State, Pipeline>,
94{
95 scope: Option<&'s mut BrokerScope<B, Layers, C, State, Pipeline>>,
98 chain: Option<Chain>,
99}
100
101impl<'s, B, Layers, C, State, Pipeline, Chain> Mounting<'s, B, Layers, C, State, Pipeline, Chain>
102where
103 B: Broker + 'static,
104 Chain: ScopeCommit<B, Layers, C, State, Pipeline>,
105{
106 pub(super) fn new(
107 chain: Chain,
108 scope: &'s mut BrokerScope<B, Layers, C, State, Pipeline>,
109 ) -> Self {
110 Self {
111 scope: Some(scope),
112 chain: Some(chain),
113 }
114 }
115
116 fn map_chain<NewChain>(
122 mut self,
123 f: impl FnOnce(Chain) -> NewChain,
124 ) -> Mounting<'s, B, Layers, C, State, Pipeline, NewChain>
125 where
126 NewChain: ScopeCommit<B, Layers, C, State, Pipeline>,
127 {
128 let chain = self
129 .chain
130 .take()
131 .expect("the guard holds its chain until the terminal or a step takes it");
132 let scope = self
133 .scope
134 .take()
135 .expect("the guard holds its scope until the terminal or a step takes it");
136 Mounting::new(f(chain), scope)
137 }
138}
139
140type Stepped<'s, B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last> =
142 Mounting<'s, B, Layers, C, State, Pipeline, RouterWith<Mount, R, Def, Attach, Last>>;
143
144type SteppedChain<Mount, R, Def, Attach, Last> = RouterWith<Mount, R, Def, Attach, Last>;
146
147impl<'s, B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last>
148 Mounting<'s, B, Layers, C, State, Pipeline, RouterWith<Mount, R, Def, Attach, Last>>
149where
150 B: Broker + 'static,
151 RouterWith<Mount, R, Def, Attach, Last>: ScopeCommit<B, Layers, C, State, Pipeline>,
152{
153 #[allow(clippy::type_complexity)] pub fn out<M, Policy, Index>(
158 self,
159 marker: M,
160 policy: Policy,
161 ) -> Stepped<
162 's,
163 B,
164 Layers,
165 C,
166 State,
167 Pipeline,
168 Mount,
169 R,
170 Def,
171 <M as OutPosition<Mount, R::Broker, Attach, Policy, Index>>::Out,
172 Index,
173 >
174 where
175 R: RouterBroker,
176 M: OutPosition<Mount, R::Broker, Attach, Policy, Index>,
177 SteppedChain<
178 Mount,
179 R,
180 Def,
181 <M as OutPosition<Mount, R::Broker, Attach, Policy, Index>>::Out,
182 Index,
183 >: ScopeCommit<B, Layers, C, State, Pipeline>,
184 {
185 self.map_chain(|chain| chain.out(marker, policy))
186 }
187
188 #[allow(clippy::type_complexity)] pub fn out_reply<Policy>(
191 self,
192 policy: Policy,
193 ) -> Stepped<
194 's,
195 B,
196 Layers,
197 C,
198 State,
199 Pipeline,
200 Mount,
201 R,
202 Def,
203 <Reply as OutPosition<Mount, R::Broker, Attach, Policy, ReplyLast>>::Out,
204 ReplyLast,
205 >
206 where
207 R: RouterBroker,
208 Reply: OutPosition<Mount, R::Broker, Attach, Policy, ReplyLast>,
209 SteppedChain<
210 Mount,
211 R,
212 Def,
213 <Reply as OutPosition<Mount, R::Broker, Attach, Policy, ReplyLast>>::Out,
214 ReplyLast,
215 >: ScopeCommit<B, Layers, C, State, Pipeline>,
216 {
217 self.out(Reply, policy)
218 }
219
220 #[allow(clippy::type_complexity)] pub fn out_retry<Policy, Index>(
223 self,
224 policy: Policy,
225 ) -> Stepped<
226 's,
227 B,
228 Layers,
229 C,
230 State,
231 Pipeline,
232 Mount,
233 R,
234 Def,
235 <Retry as OutPosition<Mount, R::Broker, Attach, Policy, Index>>::Out,
236 Index,
237 >
238 where
239 R: RouterBroker,
240 Retry: OutPosition<Mount, R::Broker, Attach, Policy, Index>,
241 SteppedChain<
242 Mount,
243 R,
244 Def,
245 <Retry as OutPosition<Mount, R::Broker, Attach, Policy, Index>>::Out,
246 Index,
247 >: ScopeCommit<B, Layers, C, State, Pipeline>,
248 {
249 self.out(Retry, policy)
250 }
251
252 #[allow(clippy::type_complexity)] pub fn max_attempts(
255 self,
256 attempts: NonZeroU32,
257 ) -> Stepped<'s, B, Layers, C, State, Pipeline, Mount, R, Def, <Attach as DeclareCap>::Out, Last>
258 where
259 Attach: DeclareCap<Step: CapOpen>,
260 SteppedChain<Mount, R, Def, <Attach as DeclareCap>::Out, Last>:
261 ScopeCommit<B, Layers, C, State, Pipeline>,
262 {
263 self.map_chain(|chain| chain.max_attempts(attempts))
264 }
265
266 #[allow(clippy::type_complexity)] pub fn dead_letter(
269 self,
270 destination: impl Into<Cow<'static, str>>,
271 ) -> Stepped<
272 's,
273 B,
274 Layers,
275 C,
276 State,
277 Pipeline,
278 Mount,
279 R,
280 Def,
281 <Attach as DeclareDeadLetter>::Out,
282 Last,
283 >
284 where
285 Attach: DeclareDeadLetter<Step: DeadLetterOpen>,
286 SteppedChain<Mount, R, Def, <Attach as DeclareDeadLetter>::Out, Last>:
287 ScopeCommit<B, Layers, C, State, Pipeline>,
288 {
289 self.map_chain(|chain| chain.dead_letter(destination))
290 }
291
292 #[allow(clippy::type_complexity)] pub fn to(
295 self,
296 destination: impl Into<Cow<'static, str>>,
297 ) -> Stepped<
298 's,
299 B,
300 Layers,
301 C,
302 State,
303 Pipeline,
304 Mount,
305 R,
306 Def,
307 <Attach as DestinationLast<Last>>::Out,
308 Last,
309 >
310 where
311 Attach: DestinationLast<Last, Step: DestinationOpen>,
312 SteppedChain<Mount, R, Def, <Attach as DestinationLast<Last>>::Out, Last>:
313 ScopeCommit<B, Layers, C, State, Pipeline>,
314 {
315 self.map_chain(|chain| chain.to(destination))
316 }
317
318 #[allow(clippy::type_complexity)] pub fn codec<Cd>(
321 self,
322 codec: Cd,
323 ) -> Stepped<
324 's,
325 B,
326 Layers,
327 C,
328 State,
329 Pipeline,
330 Mount,
331 R,
332 Def,
333 <Attach as CodecLast<Cd, Last>>::Out,
334 Last,
335 >
336 where
337 Attach: CodecLast<Cd, Last, Step: NamedStep>,
338 SteppedChain<Mount, R, Def, <Attach as CodecLast<Cd, Last>>::Out, Last>:
339 ScopeCommit<B, Layers, C, State, Pipeline>,
340 {
341 self.map_chain(|chain| chain.codec(codec))
342 }
343
344 #[allow(clippy::type_complexity)] pub fn transform<N>(
347 self,
348 transform: N,
349 ) -> Stepped<
350 's,
351 B,
352 Layers,
353 C,
354 State,
355 Pipeline,
356 Mount,
357 R,
358 Def,
359 <Attach as TransformLast<N, Last>>::Out,
360 Last,
361 >
362 where
363 R: RouterBroker<Broker = B>,
364 Attach: TransformLast<N, Last, Step: NamedStep> + AdmitsAt<N, Last, Mount, Def, B>,
365 SteppedChain<Mount, R, Def, <Attach as TransformLast<N, Last>>::Out, Last>:
366 ScopeCommit<B, Layers, C, State, Pipeline>,
367 {
368 self.map_chain(|chain| chain.transform(transform))
369 }
370
371 #[allow(clippy::type_complexity)] pub fn batch_transform<N>(
374 self,
375 transform: N,
376 ) -> Stepped<
377 's,
378 B,
379 Layers,
380 C,
381 State,
382 Pipeline,
383 Mount,
384 R,
385 Def,
386 <Attach as BatchTransformLast<N, Last>>::Out,
387 Last,
388 >
389 where
390 Attach: BatchTransformLast<N, Last, Step: ReplyStep>,
391 SteppedChain<Mount, R, Def, <Attach as BatchTransformLast<N, Last>>::Out, Last>:
392 ScopeCommit<B, Layers, C, State, Pipeline>,
393 {
394 self.map_chain(|chain| chain.batch_transform(transform))
395 }
396
397 #[allow(clippy::type_complexity)] pub fn transactional(
400 self,
401 ) -> Stepped<
402 's,
403 B,
404 Layers,
405 C,
406 State,
407 Pipeline,
408 Mount,
409 R,
410 Def,
411 <Attach as TransactionalLast<Last>>::Out,
412 Last,
413 >
414 where
415 Attach: TransactionalLast<Last, Step: ReplyStep>,
416 SteppedChain<Mount, R, Def, <Attach as TransactionalLast<Last>>::Out, Last>:
417 ScopeCommit<B, Layers, C, State, Pipeline>,
418 {
419 self.map_chain(RouterWith::transactional)
420 }
421}
422
423type EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe> =
426 Router<B, (Head, Tail), RouteCodec, RouteLayers, RoutePipe>;
427
428impl<'s, B, Layers, C, State, Pipeline, Head, Tail, RouteCodec, RouteLayers, RoutePipe>
433 Mounting<
434 's,
435 B,
436 Layers,
437 C,
438 State,
439 Pipeline,
440 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
441 >
442where
443 B: Broker + 'static,
444 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>:
445 ScopeCommit<B, Layers, C, State, Pipeline>,
446{
447 #[allow(clippy::needless_pass_by_value, clippy::type_complexity)]
454 pub fn out<M, Policy>(
455 self,
456 marker: M,
457 policy: Policy,
458 ) -> Mounting<
459 's,
460 B,
461 Layers,
462 C,
463 State,
464 Pipeline,
465 <M as RoutePosition<
466 B,
467 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
468 Policy,
469 >>::Out,
470 >
471 where
472 M: RoutePosition<B, EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>, Policy>,
473 <M as RoutePosition<
474 B,
475 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
476 Policy,
477 >>::Out: ScopeCommit<B, Layers, C, State, Pipeline>,
478 {
479 let _ = marker;
480 self.map_chain(|chain| M::bind(chain, policy))
481 }
482
483 #[allow(clippy::type_complexity)] pub fn max_attempts(
488 self,
489 attempts: NonZeroU32,
490 ) -> Mounting<
491 's,
492 B,
493 Layers,
494 C,
495 State,
496 Pipeline,
497 RouterWith<
498 DeclareMount,
499 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
500 (),
501 RouteDeclaring<Present, Absent>,
502 >,
503 >
504 where
505 Head: RetryOpen,
506 RouterWith<
507 DeclareMount,
508 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
509 (),
510 RouteDeclaring<Present, Absent>,
511 >: ScopeCommit<B, Layers, C, State, Pipeline>,
512 {
513 self.map_chain(|chain| chain.max_attempts(attempts))
514 }
515
516 #[allow(clippy::type_complexity)] pub fn dead_letter(
519 self,
520 destination: impl Into<Cow<'static, str>>,
521 ) -> Mounting<
522 's,
523 B,
524 Layers,
525 C,
526 State,
527 Pipeline,
528 RouterWith<
529 DeclareMount,
530 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
531 (),
532 RouteDeclaring<Absent, Present>,
533 >,
534 >
535 where
536 Head: RetryOpen,
537 RouterWith<
538 DeclareMount,
539 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
540 (),
541 RouteDeclaring<Absent, Present>,
542 >: ScopeCommit<B, Layers, C, State, Pipeline>,
543 {
544 self.map_chain(|chain| chain.dead_letter(destination))
545 }
546
547 #[allow(clippy::type_complexity)] pub fn out_retry<Policy>(
551 self,
552 policy: Policy,
553 ) -> Mounting<
554 's,
555 B,
556 Layers,
557 C,
558 State,
559 Pipeline,
560 <Retry as RoutePosition<
561 B,
562 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
563 Policy,
564 >>::Out,
565 >
566 where
567 Retry:
568 RoutePosition<B, EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>, Policy>,
569 <Retry as RoutePosition<
570 B,
571 EagerChain<B, Head, Tail, RouteCodec, RouteLayers, RoutePipe>,
572 Policy,
573 >>::Out: ScopeCommit<B, Layers, C, State, Pipeline>,
574 {
575 self.out(Retry, policy)
576 }
577}
578
579impl<B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last> MapPublisher
583 for Mounting<'_, B, Layers, C, State, Pipeline, RouterWith<Mount, R, Def, Attach, Last>>
584where
585 B: Broker + 'static,
586 Attach: MapPolicyLast<Last, Step: NamedStep>,
587 RouterWith<Mount, R, Def, Attach, Last>: ScopeCommit<B, Layers, C, State, Pipeline>,
588{
589 type Policy = Attach::Policy;
590
591 fn map_publisher(self, f: impl FnOnce(Self::Policy) -> Self::Policy) -> Self {
592 self.map_chain(|chain| chain.map_publisher(f))
593 }
594}
595
596impl<B, Layers, C, State, Pipeline, Chain> fmt::Debug
597 for Mounting<'_, B, Layers, C, State, Pipeline, Chain>
598where
599 B: Broker + 'static,
600 Chain: ScopeCommit<B, Layers, C, State, Pipeline>,
601{
602 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
603 f.debug_struct("Mounting").finish_non_exhaustive()
604 }
605}
606
607impl<B, Layers, C, State, Pipeline, Chain> Drop
608 for Mounting<'_, B, Layers, C, State, Pipeline, Chain>
609where
610 B: Broker + 'static,
611 Chain: ScopeCommit<B, Layers, C, State, Pipeline>,
612{
613 fn drop(&mut self) {
614 if let (Some(chain), Some(scope)) = (self.chain.take(), self.scope.take()) {
615 chain.commit_into(scope);
616 }
617 }
618}
619
620#[must_use = "a handler with Out slots is not mounted until `.build()` commits it: bind every \
629 slot with `.out(marker, policy)`, then finish the chain with `.build()`"]
630pub struct MountingSlots<'s, B, Layers, C, State, Pipeline, Chain>
631where
632 B: Broker + 'static,
633{
634 scope: Option<&'s mut BrokerScope<B, Layers, C, State, Pipeline>>,
636 chain: Option<Chain>,
637}
638
639impl<'s, B, Layers, C, State, Pipeline, Chain>
640 MountingSlots<'s, B, Layers, C, State, Pipeline, Chain>
641where
642 B: Broker + 'static,
643{
644 pub(super) fn new(
645 chain: Chain,
646 scope: &'s mut BrokerScope<B, Layers, C, State, Pipeline>,
647 ) -> Self {
648 Self {
649 scope: Some(scope),
650 chain: Some(chain),
651 }
652 }
653
654 fn take(mut self) -> (Chain, &'s mut BrokerScope<B, Layers, C, State, Pipeline>) {
660 let chain = self
661 .chain
662 .take()
663 .expect("the guard holds its chain until the terminal or a step takes it");
664 let scope = self
665 .scope
666 .take()
667 .expect("the guard holds its scope until the terminal or a step takes it");
668 (chain, scope)
669 }
670
671 fn map_chain<NewChain>(
677 self,
678 f: impl FnOnce(Chain) -> NewChain,
679 ) -> MountingSlots<'s, B, Layers, C, State, Pipeline, NewChain> {
680 let (chain, scope) = self.take();
681 MountingSlots::new(f(chain), scope)
682 }
683
684 pub fn build(self)
693 where
694 Chain: ScopeCommit<B, Layers, C, State, Pipeline>,
695 {
696 let (chain, scope) = self.take();
697 chain.commit_into(scope);
698 }
699}
700
701type SteppedSlots<'s, B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last> =
703 MountingSlots<'s, B, Layers, C, State, Pipeline, RouterWith<Mount, R, Def, Attach, Last>>;
704
705impl<'s, B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last>
706 MountingSlots<'s, B, Layers, C, State, Pipeline, RouterWith<Mount, R, Def, Attach, Last>>
707where
708 B: Broker + 'static,
709{
710 #[allow(clippy::type_complexity)] pub fn out<M, Policy, Index>(
715 self,
716 marker: M,
717 policy: Policy,
718 ) -> SteppedSlots<
719 's,
720 B,
721 Layers,
722 C,
723 State,
724 Pipeline,
725 Mount,
726 R,
727 Def,
728 <M as OutPosition<Mount, R::Broker, Attach, Policy, Index>>::Out,
729 Index,
730 >
731 where
732 R: RouterBroker,
733 M: OutPosition<Mount, R::Broker, Attach, Policy, Index>,
734 {
735 self.map_chain(|chain| chain.out(marker, policy))
736 }
737
738 #[allow(clippy::type_complexity)] pub fn out_reply<Policy>(
741 self,
742 policy: Policy,
743 ) -> SteppedSlots<
744 's,
745 B,
746 Layers,
747 C,
748 State,
749 Pipeline,
750 Mount,
751 R,
752 Def,
753 <Reply as OutPosition<Mount, R::Broker, Attach, Policy, ReplyLast>>::Out,
754 ReplyLast,
755 >
756 where
757 R: RouterBroker,
758 Reply: OutPosition<Mount, R::Broker, Attach, Policy, ReplyLast>,
759 {
760 self.out(Reply, policy)
761 }
762
763 #[allow(clippy::type_complexity)] pub fn out_retry<Policy, Index>(
766 self,
767 policy: Policy,
768 ) -> SteppedSlots<
769 's,
770 B,
771 Layers,
772 C,
773 State,
774 Pipeline,
775 Mount,
776 R,
777 Def,
778 <Retry as OutPosition<Mount, R::Broker, Attach, Policy, Index>>::Out,
779 Index,
780 >
781 where
782 R: RouterBroker,
783 Retry: OutPosition<Mount, R::Broker, Attach, Policy, Index>,
784 {
785 self.out(Retry, policy)
786 }
787
788 #[allow(clippy::type_complexity)] pub fn max_attempts(
791 self,
792 attempts: NonZeroU32,
793 ) -> SteppedSlots<
794 's,
795 B,
796 Layers,
797 C,
798 State,
799 Pipeline,
800 Mount,
801 R,
802 Def,
803 <Attach as DeclareCap>::Out,
804 Last,
805 >
806 where
807 Attach: DeclareCap<Step: CapOpen>,
808 {
809 self.map_chain(|chain| chain.max_attempts(attempts))
810 }
811
812 #[allow(clippy::type_complexity)] pub fn dead_letter(
815 self,
816 destination: impl Into<Cow<'static, str>>,
817 ) -> SteppedSlots<
818 's,
819 B,
820 Layers,
821 C,
822 State,
823 Pipeline,
824 Mount,
825 R,
826 Def,
827 <Attach as DeclareDeadLetter>::Out,
828 Last,
829 >
830 where
831 Attach: DeclareDeadLetter<Step: DeadLetterOpen>,
832 {
833 self.map_chain(|chain| chain.dead_letter(destination))
834 }
835
836 #[allow(clippy::type_complexity)] pub fn to(
839 self,
840 destination: impl Into<Cow<'static, str>>,
841 ) -> SteppedSlots<
842 's,
843 B,
844 Layers,
845 C,
846 State,
847 Pipeline,
848 Mount,
849 R,
850 Def,
851 <Attach as DestinationLast<Last>>::Out,
852 Last,
853 >
854 where
855 Attach: DestinationLast<Last, Step: DestinationOpen>,
856 {
857 self.map_chain(|chain| chain.to(destination))
858 }
859
860 #[allow(clippy::type_complexity)] pub fn codec<Cd>(
863 self,
864 codec: Cd,
865 ) -> SteppedSlots<
866 's,
867 B,
868 Layers,
869 C,
870 State,
871 Pipeline,
872 Mount,
873 R,
874 Def,
875 <Attach as CodecLast<Cd, Last>>::Out,
876 Last,
877 >
878 where
879 Attach: CodecLast<Cd, Last, Step: NamedStep>,
880 {
881 self.map_chain(|chain| chain.codec(codec))
882 }
883
884 #[allow(clippy::type_complexity)] pub fn transform<N>(
887 self,
888 transform: N,
889 ) -> SteppedSlots<
890 's,
891 B,
892 Layers,
893 C,
894 State,
895 Pipeline,
896 Mount,
897 R,
898 Def,
899 <Attach as TransformLast<N, Last>>::Out,
900 Last,
901 >
902 where
903 R: RouterBroker<Broker = B>,
904 Attach: TransformLast<N, Last, Step: NamedStep> + AdmitsAt<N, Last, Mount, Def, B>,
905 {
906 self.map_chain(|chain| chain.transform(transform))
907 }
908
909 #[allow(clippy::type_complexity)] pub fn batch_transform<N>(
912 self,
913 transform: N,
914 ) -> SteppedSlots<
915 's,
916 B,
917 Layers,
918 C,
919 State,
920 Pipeline,
921 Mount,
922 R,
923 Def,
924 <Attach as BatchTransformLast<N, Last>>::Out,
925 Last,
926 >
927 where
928 Attach: BatchTransformLast<N, Last, Step: ReplyStep>,
929 {
930 self.map_chain(|chain| chain.batch_transform(transform))
931 }
932
933 #[allow(clippy::type_complexity)] pub fn transactional(
936 self,
937 ) -> SteppedSlots<
938 's,
939 B,
940 Layers,
941 C,
942 State,
943 Pipeline,
944 Mount,
945 R,
946 Def,
947 <Attach as TransactionalLast<Last>>::Out,
948 Last,
949 >
950 where
951 Attach: TransactionalLast<Last, Step: ReplyStep>,
952 {
953 self.map_chain(RouterWith::transactional)
954 }
955}
956
957impl<B, Layers, C, State, Pipeline, Mount, R, Def, Attach, Last> MapPublisher
959 for MountingSlots<'_, B, Layers, C, State, Pipeline, RouterWith<Mount, R, Def, Attach, Last>>
960where
961 B: Broker + 'static,
962 Attach: MapPolicyLast<Last, Step: NamedStep>,
963{
964 type Policy = Attach::Policy;
965
966 fn map_publisher(self, f: impl FnOnce(Self::Policy) -> Self::Policy) -> Self {
967 self.map_chain(|chain| chain.map_publisher(f))
968 }
969}
970
971impl<B, Layers, C, State, Pipeline, Chain> fmt::Debug
972 for MountingSlots<'_, B, Layers, C, State, Pipeline, Chain>
973where
974 B: Broker + 'static,
975{
976 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977 f.debug_struct("MountingSlots").finish_non_exhaustive()
978 }
979}
980
981impl<B, Layers, C, State, Pipeline, Chain> Drop
982 for MountingSlots<'_, B, Layers, C, State, Pipeline, Chain>
983where
984 B: Broker + 'static,
985{
986 fn drop(&mut self) {
987 assert!(
992 self.chain.is_none(),
993 "a handler with Out slots was included but never mounted: bind each slot with \
994 .out(marker, policy) and finish the chain with .build()"
995 );
996 }
997}