1use core::future::Future;
4use core::marker::PhantomData;
5use core::num::NonZeroU64;
6
7use super::addressing::{Address, EndpointAddress, EstablishedActor, EstablishedRecipient};
8use crate::next::Never;
9use crate::{
10 ActionItem, Actions, Behavior, BehaviorAddr, BehaviorBase, InterpretationProgress,
11 ItemSettlement, Protocol, SettledItem, finish_item, prepare_item,
12};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub struct CreationId(NonZeroU64);
20
21impl CreationId {
22 #[must_use]
29 pub const fn get(self) -> u64 {
30 self.0.get()
31 }
32}
33
34#[derive(Debug, PartialEq, Eq)]
36pub struct CreationSequence {
37 next: Option<NonZeroU64>,
38}
39
40impl CreationSequence {
41 #[must_use]
43 pub const fn new() -> Self {
44 Self {
45 next: Some(NonZeroU64::MIN),
46 }
47 }
48
49 pub fn issue(&mut self) -> Option<CreationId> {
52 let value = self.next?;
53 self.next = value.checked_add(1);
54 Some(CreationId(value))
55 }
56}
57
58impl Default for CreationSequence {
59 fn default() -> Self {
60 Self::new()
61 }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum CreationKind {
67 Birth,
69 Replacement {
71 previous: CreationId,
73 },
74}
75
76impl CreationKind {
77 #[must_use]
78 pub const fn replacement(previous: CreationId) -> Self {
79 Self::Replacement { previous }
80 }
81}
82
83#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct CreateChild<A: Address, New> {
101 id: CreationId,
102 child: New,
103 kind: CreationKind,
104 address: PhantomData<fn() -> A>,
105}
106
107impl<A: Address, New> CreateChild<A, New> {
108 #[must_use]
109 pub(crate) const fn from_parts(id: CreationId, child: New, kind: CreationKind) -> Self {
110 Self {
111 id,
112 child,
113 kind,
114 address: PhantomData,
115 }
116 }
117
118 #[must_use]
119 pub const fn birth(id: CreationId, child: New) -> Self {
120 Self::from_parts(id, child, CreationKind::Birth)
121 }
122
123 #[must_use]
124 pub const fn replacement(id: CreationId, previous: CreationId, child: New) -> Self {
125 Self::from_parts(id, child, CreationKind::replacement(previous))
126 }
127
128 #[must_use]
129 pub const fn id(&self) -> CreationId {
130 self.id
131 }
132
133 #[must_use]
134 pub const fn kind(&self) -> CreationKind {
135 self.kind
136 }
137
138 #[must_use]
139 pub const fn child(&self) -> &New {
140 &self.child
141 }
142
143 #[must_use]
150 pub fn into_parts(self) -> (CreationId, New, CreationKind) {
151 (self.id, self.child, self.kind)
152 }
153}
154
155#[derive(Debug, Clone, PartialEq, Eq)]
161pub struct Creations<Item> {
162 items: Vec<Item>,
163}
164
165impl<Item> Creations<Item> {
166 #[must_use]
168 pub const fn empty() -> Self {
169 Self { items: Vec::new() }
170 }
171
172 #[must_use]
173 pub fn one(item: Item) -> Self {
174 Self { items: vec![item] }
175 }
176
177 pub fn into_one(self) -> Result<Item, Self> {
183 let one: Result<[Item; 1], Vec<Item>> = self.items.try_into();
184 match one {
185 Ok([item]) => Ok(item),
186 Err(items) => Err(Self { items }),
187 }
188 }
189
190 #[must_use]
191 pub fn and(mut self, item: Item) -> Self {
192 self.items.push(item);
193 self
194 }
195
196 #[must_use]
198 pub fn map<Mapped>(self, mut map: impl FnMut(Item) -> Mapped) -> Creations<Mapped> {
199 Creations::from_items(self.items.into_iter().map(&mut map).collect())
200 }
201
202 #[must_use]
203 pub fn len(&self) -> usize {
204 self.items.len()
205 }
206
207 #[must_use]
208 pub fn is_empty(&self) -> bool {
209 self.items.is_empty()
210 }
211
212 pub(crate) fn from_items(items: Vec<Item>) -> Self {
213 Self { items }
214 }
215
216 pub fn iter(&self) -> core::slice::Iter<'_, Item> {
217 self.items.iter()
218 }
219}
220
221impl<Item> Default for Creations<Item> {
222 fn default() -> Self {
223 Self::empty()
224 }
225}
226
227impl<Item> Extend<Item> for Creations<Item> {
228 fn extend<Items: IntoIterator<Item = Item>>(&mut self, items: Items) {
229 self.items.extend(items);
230 }
231}
232
233impl<Item> FromIterator<Item> for Creations<Item> {
234 fn from_iter<Items: IntoIterator<Item = Item>>(items: Items) -> Self {
235 Self::from_items(items.into_iter().collect())
236 }
237}
238
239impl<'a, Item> IntoIterator for &'a Creations<Item> {
240 type Item = &'a Item;
241 type IntoIter = core::slice::Iter<'a, Item>;
242
243 fn into_iter(self) -> Self::IntoIter {
244 self.iter()
245 }
246}
247
248impl<Item> IntoIterator for Creations<Item> {
249 type Item = Item;
250 type IntoIter = std::vec::IntoIter<Item>;
251
252 fn into_iter(self) -> Self::IntoIter {
253 self.items.into_iter()
254 }
255}
256
257pub trait ChildRole<Parent: Behavior> {
263 type Child: Behavior;
265
266 type Position: ChildPosition<<Parent::Birth as BirthMode>::Child, Self::Child>;
268}
269
270pub trait ChildOccurrence<Parent: Behavior>: Sized {
284 type Resolution: ChildOccurrenceResolution<Parent, Self>;
286}
287
288pub struct DeclaredChildOccurrence;
294
295#[doc(hidden)]
299pub struct StructuralChildOccurrence<Position>(PhantomData<fn() -> Position>);
300
301pub trait ResolveChildOccurrence<Occurrence>:
374 Behavior + sealed::ResolveChildOccurrence<Occurrence>
375{
376 type Child: Behavior;
378
379 type Position: ChildPosition<<Self::Birth as BirthMode>::Child, Self::Child>;
381}
382
383impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
384where
385 Emitter: Behavior + BehaviorBase + sealed::ResolveChildOccurrence<Occurrence>,
386 Emitter::Base: Behavior,
387 Occurrence: ChildOccurrence<Emitter::Base>,
388 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
389{
390 type Child =
391 <Occurrence::Resolution as ResolveChildOccurrenceDescriptor<Emitter, Occurrence>>::Child;
392 type Position =
393 <Occurrence::Resolution as ResolveChildOccurrenceDescriptor<Emitter, Occurrence>>::Position;
394}
395
396pub type ResolvedChild<Emitter, Occurrence> =
398 <Emitter as ResolveChildOccurrence<Occurrence>>::Child;
399
400pub type ResolvedChildPosition<Emitter, Occurrence> =
403 <Emitter as ResolveChildOccurrence<Occurrence>>::Position;
404
405pub type RoleChild<Parent, Role> = <Role as ChildRole<Parent>>::Child;
407
408pub type RoleProtocol<Parent, Role> = <RoleChild<Parent, Role> as Behavior>::Protocol;
410
411#[derive(Debug, Clone, PartialEq, Eq)]
417pub struct RoutedCreation<A: Address, New> {
418 creation: CreateChild<A, New>,
419 route: A::Nonce,
420}
421
422impl<A: Address, New> RoutedCreation<A, New> {
423 #[must_use]
425 pub const fn new(creation: CreateChild<A, New>, route: A::Nonce) -> Self {
426 Self { creation, route }
427 }
428
429 #[must_use]
430 pub const fn id(&self) -> CreationId {
431 self.creation.id()
432 }
433
434 #[must_use]
435 pub const fn kind(&self) -> CreationKind {
436 self.creation.kind()
437 }
438
439 #[must_use]
440 pub const fn route(&self) -> A::Nonce {
441 self.route
442 }
443
444 #[must_use]
447 pub fn child_mut(&mut self) -> &mut New {
448 &mut self.creation.child
449 }
450
451 #[must_use]
452 pub fn into_parts(self) -> (CreateChild<A, New>, A::Nonce) {
453 (self.creation, self.route)
454 }
455}
456
457#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
460pub enum AllocationRejection {
461 #[error("fresh actor-address allocation is exhausted")]
463 Exhausted,
464 #[error("the proposed actor address is already claimed")]
467 AddressAlreadyClaimed,
468}
469
470#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
472pub enum CreationRejection {
473 #[error("fresh allocation failed: {0}")]
475 Allocation(AllocationRejection),
476 #[error("child initialization failed")]
478 InitializationFailed,
479 #[error("the interpreter could not install and commit the child")]
481 EnvironmentFailed,
482}
483
484#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
486#[error("the creator child namespace is exhausted")]
487pub struct ChildNamespaceExhausted;
488
489impl<A, New> ActionItem for Creations<CreateChild<A, New>>
490where
491 A: Address,
492 A::Nonce: Send,
493 New: Send,
494{
495 type Custody = (Option<Self>, Option<Self::Reply>);
496 type Input<'a>
497 = &'a mut Option<Self>
498 where
499 Self: 'a;
500 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
501
502 fn prepare_interpretation(
503 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
504 ) {
505 prepare_item::<Self>(progress);
506 }
507 fn interpretation_input<'a>(
508 custody: &'a mut Self::Custody,
509 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
510 where
511 Self: 'a,
512 {
513 let (input, received) = custody;
514 if input.is_some() && received.is_none() {
515 Some((input, received))
516 } else {
517 None
518 }
519 }
520 fn finish_interpretation(
521 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
522 ) {
523 finish_item::<Self>(progress);
524 }
525
526 type Accepted = Creations<RoutedCreation<A, New>>;
527 type Rejection = ChildNamespaceExhausted;
528 type Prerequisite = Never;
529}
530
531pub struct CommittedChild<C, Occurrence>
535where
536 C: Behavior,
537 BehaviorAddr<C>: EndpointAddress,
538{
539 id: CreationId,
540 kind: CreationKind,
541 actor: EstablishedActor<C>,
542 occurrence: PhantomData<fn() -> Occurrence>,
543}
544
545impl<C, Occurrence> CommittedChild<C, Occurrence>
546where
547 C: Behavior,
548 BehaviorAddr<C>: EndpointAddress,
549{
550 #[must_use]
554 pub const fn new(id: CreationId, kind: CreationKind, actor: EstablishedActor<C>) -> Self {
555 Self {
556 id,
557 kind,
558 actor,
559 occurrence: PhantomData,
560 }
561 }
562
563 #[must_use]
564 pub const fn id(&self) -> CreationId {
565 self.id
566 }
567
568 #[must_use]
569 pub const fn kind(&self) -> CreationKind {
570 self.kind
571 }
572
573 #[must_use]
574 pub fn actor(&self) -> EstablishedActor<C> {
575 self.actor.clone()
576 }
577
578 #[must_use]
579 pub fn into_parts(self) -> (CreationId, CreationKind, EstablishedActor<C>) {
580 (self.id, self.kind, self.actor)
581 }
582}
583
584pub enum EstablishedCreation<C, Occurrence>
623where
624 C: Behavior,
625 BehaviorAddr<C>: EndpointAddress,
626{
627 Installed(CommittedChild<C, Occurrence>),
628 Rejected {
629 id: CreationId,
630 kind: CreationKind,
631 reason: CreationRejection,
632 occurrence: PhantomData<fn() -> Occurrence>,
633 },
634}
635
636impl<C, Occurrence> EstablishedCreation<C, Occurrence>
637where
638 C: Behavior,
639 BehaviorAddr<C>: EndpointAddress,
640{
641 #[must_use]
642 pub const fn installed(child: CommittedChild<C, Occurrence>) -> Self {
643 Self::Installed(child)
644 }
645
646 #[must_use]
647 pub const fn rejected(id: CreationId, kind: CreationKind, reason: CreationRejection) -> Self {
648 Self::Rejected {
649 id,
650 kind,
651 reason,
652 occurrence: PhantomData,
653 }
654 }
655
656 #[must_use]
657 pub const fn id(&self) -> CreationId {
658 match self {
659 Self::Installed(child) => child.id(),
660 Self::Rejected { id, .. } => *id,
661 }
662 }
663
664 #[must_use]
665 pub const fn kind(&self) -> CreationKind {
666 match self {
667 Self::Installed(child) => child.kind(),
668 Self::Rejected { kind, .. } => *kind,
669 }
670 }
671
672 pub fn into_recipient(self) -> Result<EstablishedRecipient<C::Protocol>, CreationRejection> {
678 match self {
679 Self::Installed(child) => Ok(child.into_parts().2.into_recipient()),
680 Self::Rejected { reason, .. } => Err(reason),
681 }
682 }
683
684 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, CreationRejection> {
691 match self {
692 Self::Installed(child) => Ok(child),
693 Self::Rejected { reason, .. } => Err(reason),
694 }
695 }
696}
697
698pub enum ChildCreationOutcome<C, Occurrence>
724where
725 C: Behavior,
726 BehaviorAddr<C>: EndpointAddress,
727{
728 Established(CommittedChild<C, Occurrence>),
730 Unavailable {
733 id: CreationId,
735 kind: CreationKind,
737 },
738 InitializationRejected {
740 creation: RoutedCreation<BehaviorAddr<C>, C>,
742 error: C::Error,
744 },
745 InitializationPanicked {
750 creation: RoutedCreation<BehaviorAddr<C>, C>,
752 },
753 HostRejected {
755 creation: RoutedCreation<BehaviorAddr<C>, C>,
757 initialization: Actions<BehaviorAddr<C>, C::Ph, C::Sends, C::Birth>,
759 reason: CreationRejection,
761 },
762}
763
764impl<C, Occurrence> ChildCreationOutcome<C, Occurrence>
765where
766 C: Behavior,
767 BehaviorAddr<C>: EndpointAddress,
768{
769 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, Self> {
779 match self {
780 Self::Established(child) => Ok(child),
781 other => Err(other),
782 }
783 }
784
785 pub fn into_actor(self) -> Result<EstablishedActor<C>, Self> {
790 self.into_committed().map(|child| child.into_parts().2)
791 }
792}
793
794#[must_use = "a child-creation settlement must be admitted or retained"]
802pub struct ChildCreationSettled<C, Occurrence>
803where
804 C: Behavior,
805 BehaviorAddr<C>: EndpointAddress,
806{
807 settlement: SettledItem<
808 RoutedCreation<BehaviorAddr<C>, C>,
809 ItemSettlement<
810 RoutedCreation<BehaviorAddr<C>, C>,
811 ChildCreationOutcome<C, Occurrence>,
812 CreationRejection,
813 Never,
814 >,
815 >,
816}
817
818impl<C, Occurrence> ChildCreationSettled<C, Occurrence>
819where
820 C: Behavior,
821 BehaviorAddr<C>: EndpointAddress,
822{
823 #[must_use]
824 pub const fn new(
825 settlement: SettledItem<
826 RoutedCreation<BehaviorAddr<C>, C>,
827 ItemSettlement<
828 RoutedCreation<BehaviorAddr<C>, C>,
829 ChildCreationOutcome<C, Occurrence>,
830 CreationRejection,
831 Never,
832 >,
833 >,
834 ) -> Self {
835 Self { settlement }
836 }
837
838 #[must_use]
840 pub fn into_settlement(
841 self,
842 ) -> SettledItem<
843 RoutedCreation<BehaviorAddr<C>, C>,
844 ItemSettlement<
845 RoutedCreation<BehaviorAddr<C>, C>,
846 ChildCreationOutcome<C, Occurrence>,
847 CreationRejection,
848 Never,
849 >,
850 > {
851 self.settlement
852 }
853}
854
855impl<C, Occurrence> core::fmt::Debug for ChildCreationSettled<C, Occurrence>
856where
857 C: Behavior,
858 BehaviorAddr<C>: EndpointAddress,
859{
860 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
861 formatter
862 .debug_struct("ChildCreationSettled")
863 .finish_non_exhaustive()
864 }
865}
866
867pub struct CreationCorrelation<P, Occurrence>
890where
891 P: Protocol,
892{
893 id: CreationId,
894 occurrence: PhantomData<fn() -> (P, Occurrence)>,
895}
896
897impl<P, Occurrence> CreationCorrelation<P, Occurrence>
898where
899 P: Protocol,
900{
901 #[must_use]
902 pub const fn new(id: CreationId) -> Self {
903 Self {
904 id,
905 occurrence: PhantomData,
906 }
907 }
908
909 #[must_use]
910 pub const fn id(self) -> CreationId {
911 self.id
912 }
913}
914
915impl<P, Occurrence> Copy for CreationCorrelation<P, Occurrence> where P: Protocol {}
916
917impl<P, Occurrence> Clone for CreationCorrelation<P, Occurrence>
918where
919 P: Protocol,
920{
921 fn clone(&self) -> Self {
922 *self
923 }
924}
925
926impl<P, Occurrence> core::fmt::Debug for CreationCorrelation<P, Occurrence>
927where
928 P: Protocol,
929{
930 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
931 formatter
932 .debug_tuple("CreationCorrelation")
933 .field(&self.id)
934 .finish()
935 }
936}
937
938impl<P, Occurrence> PartialEq for CreationCorrelation<P, Occurrence>
939where
940 P: Protocol,
941{
942 fn eq(&self, other: &Self) -> bool {
943 self.id == other.id
944 }
945}
946
947impl<P, Occurrence> Eq for CreationCorrelation<P, Occurrence> where P: Protocol {}
948
949pub struct ChildDelivery<P, Occurrence>
956where
957 P: Protocol,
958{
959 pub creation: CreationId,
960 pub message: P::Msg,
961 occurrence: PhantomData<fn() -> Occurrence>,
962}
963
964pub struct ChildInput<Child, Source, Input, Occurrence>
977where
978 Child: Behavior,
979{
980 pub creation: CreationId,
982 pub input: Input,
984 marker: PhantomData<fn() -> (Child, Source, Occurrence)>,
985}
986
987#[derive(Clone, Copy, Debug, Eq, PartialEq)]
989pub enum ChildDeliveryReason {
990 MissingBinding,
991 ClosedRecipient,
992}
993
994#[derive(Clone, Copy, Debug, Eq, PartialEq)]
996pub enum ChildInputReason {
997 MissingBinding,
998 ClosedControlLane,
999}
1000
1001#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1008pub struct ChildReport<R> {
1009 pub child: CreationId,
1011 pub report: R,
1013}
1014
1015impl<R> ChildReport<R> {
1016 #[must_use]
1018 pub const fn new(child: CreationId, report: R) -> Self {
1019 Self { child, report }
1020 }
1021}
1022
1023impl<R> From<(CreationId, crate::ReportToParent<R>)> for ChildReport<R> {
1024 fn from((child, request): (CreationId, crate::ReportToParent<R>)) -> Self {
1025 Self::new(child, request.into_inner())
1026 }
1027}
1028
1029impl<Child, Source, Input, Occurrence> ChildInput<Child, Source, Input, Occurrence>
1030where
1031 Child: Behavior,
1032 Child::Event: crate::ChildInputIngress<Source, Input>,
1033{
1034 #[must_use]
1036 pub const fn after(creation: CreationId, input: Input) -> Self {
1037 Self {
1038 creation,
1039 input,
1040 marker: PhantomData,
1041 }
1042 }
1043}
1044
1045impl<Child, Source, Input, Occurrence> Clone for ChildInput<Child, Source, Input, Occurrence>
1046where
1047 Child: Behavior,
1048 Input: Clone,
1049{
1050 fn clone(&self) -> Self {
1051 Self {
1052 creation: self.creation,
1053 input: self.input.clone(),
1054 marker: PhantomData,
1055 }
1056 }
1057}
1058
1059impl<P, Occurrence> ChildDelivery<P, Occurrence>
1060where
1061 P: Protocol,
1062{
1063 #[must_use]
1064 pub const fn after(creation: CreationId, message: P::Msg) -> Self {
1065 Self {
1066 creation,
1067 message,
1068 occurrence: PhantomData,
1069 }
1070 }
1071}
1072
1073impl<P, Occurrence> Clone for ChildDelivery<P, Occurrence>
1074where
1075 P: Protocol,
1076 P::Msg: Clone,
1077{
1078 fn clone(&self) -> Self {
1079 Self {
1080 creation: self.creation,
1081 message: self.message.clone(),
1082 occurrence: PhantomData,
1083 }
1084 }
1085}
1086
1087impl<P, Occurrence> ActionItem for ChildDelivery<P, Occurrence>
1088where
1089 P: Protocol,
1090 P::Msg: Send,
1091{
1092 type Custody = (Option<Self>, Option<Self::Reply>);
1093 type Input<'a>
1094 = &'a mut Option<Self>
1095 where
1096 Self: 'a;
1097 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1098
1099 fn prepare_interpretation(
1100 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1101 ) {
1102 prepare_item::<Self>(progress);
1103 }
1104 fn interpretation_input<'a>(
1105 custody: &'a mut Self::Custody,
1106 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1107 where
1108 Self: 'a,
1109 {
1110 let (input, received) = custody;
1111 if input.is_some() && received.is_none() {
1112 Some((input, received))
1113 } else {
1114 None
1115 }
1116 }
1117 fn finish_interpretation(
1118 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1119 ) {
1120 finish_item::<Self>(progress);
1121 }
1122
1123 type Accepted = ();
1124 type Rejection = ChildDeliveryReason;
1125 type Prerequisite = CreationCorrelation<P, Occurrence>;
1126}
1127
1128impl<Child, Source, Input, Occurrence> ActionItem for ChildInput<Child, Source, Input, Occurrence>
1129where
1130 Child: Behavior,
1131 Input: Send,
1132{
1133 type Custody = (Option<Self>, Option<Self::Reply>);
1134 type Input<'a>
1135 = &'a mut Option<Self>
1136 where
1137 Self: 'a;
1138 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1139
1140 fn prepare_interpretation(
1141 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1142 ) {
1143 prepare_item::<Self>(progress);
1144 }
1145 fn interpretation_input<'a>(
1146 custody: &'a mut Self::Custody,
1147 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1148 where
1149 Self: 'a,
1150 {
1151 let (input, received) = custody;
1152 if input.is_some() && received.is_none() {
1153 Some((input, received))
1154 } else {
1155 None
1156 }
1157 }
1158 fn finish_interpretation(
1159 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1160 ) {
1161 finish_item::<Self>(progress);
1162 }
1163
1164 type Accepted = ();
1165 type Rejection = ChildInputReason;
1166 type Prerequisite = CreationCorrelation<Child::Protocol, Occurrence>;
1167}
1168
1169pub trait EstablishChild<Occurrence, C>
1235where
1236 C: Behavior,
1237 BehaviorAddr<C>: EndpointAddress,
1238{
1239 fn establish_child(
1241 &mut self,
1242 creation: RoutedCreation<BehaviorAddr<C>, C>,
1243 ) -> impl Future<
1244 Output = ItemSettlement<
1245 RoutedCreation<BehaviorAddr<C>, C>,
1246 ChildCreationOutcome<C, Occurrence>,
1247 CreationRejection,
1248 Never,
1249 >,
1250 > + Send;
1251}
1252
1253#[doc(hidden)]
1258pub trait ChildCreationProduct<A: Address, Occurrence>: Sized {
1259 type Result;
1260}
1261
1262pub trait DispatchBirth<A: Address, Host>: ChildCreationProduct<A, ChildHead> + Sized {
1271 fn dispatch_birth(
1274 self,
1275 id: CreationId,
1276 route: A::Nonce,
1277 kind: CreationKind,
1278 host: &mut Host,
1279 ) -> impl Future<
1280 Output = ItemSettlement<
1281 RoutedCreation<A, Self>,
1282 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1283 CreationRejection,
1284 Never,
1285 >,
1286 > + Send;
1287}
1288
1289trait CreateSelectedChild<A: Address, Occurrence, Host>:
1290 ChildCreationProduct<A, Occurrence> + Sized
1291{
1292 fn dispatch_birth_at(
1293 self,
1294 id: CreationId,
1295 route: A::Nonce,
1296 kind: CreationKind,
1297 host: &mut Host,
1298 ) -> impl Future<
1299 Output = ItemSettlement<
1300 RoutedCreation<A, Self>,
1301 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1302 CreationRejection,
1303 Never,
1304 >,
1305 > + Send;
1306}
1307
1308impl<A, Child, Host> DispatchBirth<A, Host> for Child
1309where
1310 A: Address,
1311 Child: CreateSelectedChild<A, ChildHead, Host>,
1312{
1313 fn dispatch_birth(
1314 self,
1315 id: CreationId,
1316 route: A::Nonce,
1317 kind: CreationKind,
1318 host: &mut Host,
1319 ) -> impl Future<
1320 Output = ItemSettlement<
1321 RoutedCreation<A, Self>,
1322 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1323 CreationRejection,
1324 Never,
1325 >,
1326 > + Send {
1327 self.dispatch_birth_at(id, route, kind, host)
1328 }
1329}
1330
1331#[derive(Debug, Clone, PartialEq, Eq)]
1415pub enum ChildChoice<Head, Tail> {
1416 Head(Head),
1418 Tail(Tail),
1420}
1421
1422#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1424pub struct ChildHead;
1425
1426#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1428pub struct ChildTail<Position>(PhantomData<fn() -> Position>);
1429
1430pub trait ChildPosition<Children, Child: Behavior>: sealed::ChildPosition {}
1483
1484impl sealed::ChildPosition for ChildHead {}
1485
1486impl<Child: Behavior> ChildPosition<Child, Child> for ChildHead {}
1487
1488impl<Head: Behavior, Tail> ChildPosition<ChildChoice<Head, Tail>, Head> for ChildHead {}
1489
1490impl<Position> sealed::ChildPosition for ChildTail<Position> {}
1491
1492impl<Head, Tail, Position, Child> ChildPosition<ChildChoice<Head, Tail>, Child>
1493 for ChildTail<Position>
1494where
1495 Child: Behavior,
1496 Position: ChildPosition<Tail, Child>,
1497{
1498}
1499
1500pub trait BirthNodeAppend<Tail>: sealed::BirthNode + Sized
1522where
1523 Tail: sealed::BirthNode,
1524{
1525 type Output: sealed::BirthNode;
1528
1529 fn append_prefix(self) -> Self::Output;
1532
1533 fn append_tail(tail: Tail) -> Self::Output;
1535
1536 #[must_use]
1538 fn append_creations<A: Address>(
1539 prefix: Creations<CreateChild<A, Self>>,
1540 tail: Creations<CreateChild<A, Tail>>,
1541 ) -> Creations<CreateChild<A, Self::Output>> {
1542 let mut combined = Vec::with_capacity(prefix.len() + tail.len());
1543 combined.extend(prefix.into_iter().map(|creation| {
1544 let (id, child, kind) = creation.into_parts();
1545 CreateChild::from_parts(id, Self::append_prefix(child), kind)
1546 }));
1547 combined.extend(tail.into_iter().map(|creation| {
1548 let (id, child, kind) = creation.into_parts();
1549 CreateChild::from_parts(id, Self::append_tail(child), kind)
1550 }));
1551 Creations::from_items(combined)
1552 }
1553}
1554
1555impl<Tail> BirthNodeAppend<Tail> for Never
1556where
1557 Tail: sealed::BirthNode,
1558{
1559 type Output = Tail;
1560
1561 fn append_prefix(self) -> Self::Output {
1562 match self {}
1563 }
1564
1565 fn append_tail(tail: Tail) -> Self::Output {
1566 tail
1567 }
1568}
1569
1570impl<Node> BirthNodeAppend<Never> for Node
1571where
1572 Node: sealed::NonEmptyBirthNode,
1573{
1574 type Output = Node;
1575
1576 fn append_prefix(self) -> Self::Output {
1577 self
1578 }
1579
1580 fn append_tail(tail: Never) -> Self::Output {
1581 match tail {}
1582 }
1583}
1584
1585impl<Child, Tail> BirthNodeAppend<Tail> for Child
1586where
1587 Child: Behavior,
1588 Tail: sealed::NonEmptyBirthNode,
1589{
1590 type Output = ChildChoice<Child, Tail>;
1591
1592 fn append_prefix(self) -> Self::Output {
1593 ChildChoice::Head(self)
1594 }
1595
1596 fn append_tail(tail: Tail) -> Self::Output {
1597 ChildChoice::Tail(tail)
1598 }
1599}
1600
1601impl<Head, Rest, Tail> BirthNodeAppend<Tail> for ChildChoice<Head, Rest>
1602where
1603 Head: Behavior,
1604 Rest: sealed::BirthNode + BirthNodeAppend<Tail>,
1605 Tail: sealed::NonEmptyBirthNode,
1606 Rest::Output: sealed::BirthNode,
1607{
1608 type Output = ChildChoice<Head, Rest::Output>;
1609
1610 fn append_prefix(self) -> Self::Output {
1611 match self {
1612 ChildChoice::Head(head) => ChildChoice::Head(head),
1613 ChildChoice::Tail(rest) => ChildChoice::Tail(rest.append_prefix()),
1614 }
1615 }
1616
1617 fn append_tail(tail: Tail) -> Self::Output {
1618 ChildChoice::Tail(Rest::append_tail(tail))
1619 }
1620}
1621
1622impl<Parent: Behavior> ChildOccurrence<Parent> for ChildHead {
1623 type Resolution = StructuralChildOccurrence<Self>;
1624}
1625
1626impl<Parent: Behavior, Position> ChildOccurrence<Parent> for ChildTail<Position> {
1627 type Resolution = StructuralChildOccurrence<Self>;
1628}
1629
1630#[doc(hidden)]
1637pub trait ChildOccurrenceResolution<Parent: Behavior, Occurrence>:
1638 sealed::ChildOccurrenceDescriptor + sealed::OccurrenceResolution<Parent, Occurrence>
1639{
1640}
1641
1642impl<Parent, Occurrence> ChildOccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1643where
1644 Parent: Behavior,
1645 Occurrence: ChildRole<Parent>,
1646{
1647}
1648
1649impl<Parent: Behavior> ChildOccurrenceResolution<Parent, ChildHead>
1650 for StructuralChildOccurrence<ChildHead>
1651{
1652}
1653
1654impl<Parent: Behavior, Position> ChildOccurrenceResolution<Parent, ChildTail<Position>>
1655 for StructuralChildOccurrence<ChildTail<Position>>
1656{
1657}
1658
1659#[doc(hidden)]
1661pub trait ResolveChildOccurrenceDescriptor<Emitter: Behavior, Occurrence>:
1662 sealed::ChildOccurrenceDescriptor + sealed::ResolveDescriptor<Emitter, Occurrence>
1663{
1664 type Child: Behavior;
1665 type Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Self::Child>;
1666}
1667
1668impl<Emitter, Occurrence, Position> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1669 for StructuralChildOccurrence<Position>
1670where
1671 Emitter: Behavior,
1672 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1673 Position: ChildPosition<
1674 <Emitter::Birth as BirthMode>::Child,
1675 <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child,
1676 >,
1677{
1678 type Child = <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child;
1679 type Position = Position;
1680}
1681
1682impl<Emitter, Occurrence> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1683 for DeclaredChildOccurrence
1684where
1685 Emitter:
1686 Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol> + BehaviorBase,
1687 Emitter::Base: Behavior,
1688 Occurrence: ChildRole<Emitter::Base>,
1689 <Emitter::Birth as BirthMode>::Child:
1690 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1691 Occurrence::Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1692{
1693 type Child = Occurrence::Child;
1694 type Position = Occurrence::Position;
1695}
1696
1697#[doc(hidden)]
1699pub trait BirthNodeAt<Position>: sealed::BirthNode {
1700 type Child: Behavior;
1701}
1702
1703impl<Child: Behavior> BirthNodeAt<ChildHead> for Child {
1704 type Child = Child;
1705}
1706
1707impl<Head: Behavior, Tail> BirthNodeAt<ChildHead> for ChildChoice<Head, Tail>
1708where
1709 Tail: sealed::BirthNode,
1710{
1711 type Child = Head;
1712}
1713
1714impl<Head, Tail, Position> BirthNodeAt<ChildTail<Position>> for ChildChoice<Head, Tail>
1715where
1716 Head: Behavior,
1717 Tail: BirthNodeAt<Position>,
1718{
1719 type Child = <Tail as BirthNodeAt<Position>>::Child;
1720}
1721
1722pub trait ChildOccurrenceShape {
1752 type Empty;
1754}
1755
1756pub trait ChildOccurrenceMember<Occurrence, Child: Behavior, Tail>: ChildOccurrenceShape {
1836 type Member;
1838}
1839
1840pub trait ChildOccurrenceProduct<Shape>: sealed::BirthNode
1871where
1872 Shape: ChildOccurrenceShape,
1873{
1874 type Product;
1876}
1877
1878#[doc(hidden)]
1881pub trait ChildOccurrenceProductAt<Occurrence, Shape>: sealed::BirthNode
1882where
1883 Shape: ChildOccurrenceShape,
1884{
1885 type Product;
1886}
1887
1888impl<Node, Shape> ChildOccurrenceProduct<Shape> for Node
1889where
1890 Node: ChildOccurrenceProductAt<ChildHead, Shape>,
1891 Shape: ChildOccurrenceShape,
1892{
1893 type Product = <Node as ChildOccurrenceProductAt<ChildHead, Shape>>::Product;
1894}
1895
1896impl<Occurrence, Shape, Child> ChildOccurrenceProductAt<Occurrence, Shape> for Child
1897where
1898 Shape: ChildOccurrenceShape
1899 + ChildOccurrenceMember<Occurrence, Child, <Shape as ChildOccurrenceShape>::Empty>,
1900 Child: Behavior,
1901{
1902 type Product = <Shape as ChildOccurrenceMember<
1903 Occurrence,
1904 Child,
1905 <Shape as ChildOccurrenceShape>::Empty,
1906 >>::Member;
1907}
1908
1909impl<Occurrence, Shape, Head, Tail> ChildOccurrenceProductAt<Occurrence, Shape>
1910 for ChildChoice<Head, Tail>
1911where
1912 Shape: ChildOccurrenceShape
1913 + ChildOccurrenceMember<
1914 Occurrence,
1915 Head,
1916 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1917 >,
1918 Head: Behavior,
1919 Tail: ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>,
1920{
1921 type Product = <Shape as ChildOccurrenceMember<
1922 Occurrence,
1923 Head,
1924 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1925 >>::Member;
1926}
1927
1928impl<Occurrence, Shape> ChildOccurrenceProductAt<Occurrence, Shape> for Never
1929where
1930 Shape: ChildOccurrenceShape,
1931{
1932 type Product = Shape::Empty;
1933}
1934
1935pub type ChildOccurrences<Node, Shape> = <Node as ChildOccurrenceProduct<Shape>>::Product;
1937
1938mod sealed {
1939 use super::{
1940 Behavior, BehaviorBase, BirthMode, BirthNodeAt, ChildChoice, ChildHead, ChildOccurrence,
1941 ChildRole, ChildTail, DeclaredChildOccurrence, Never, ResolveChildOccurrenceDescriptor,
1942 StructuralChildOccurrence,
1943 };
1944
1945 pub trait BirthNode {}
1946
1947 pub trait NonEmptyBirthNode: BirthNode {}
1948
1949 impl<Child: Behavior> BirthNode for Child {}
1950 impl<Child: Behavior> NonEmptyBirthNode for Child {}
1951
1952 impl<Head, Tail> BirthNode for ChildChoice<Head, Tail>
1953 where
1954 Head: Behavior,
1955 Tail: BirthNode,
1956 {
1957 }
1958
1959 impl<Head, Tail> NonEmptyBirthNode for ChildChoice<Head, Tail>
1960 where
1961 Head: Behavior,
1962 Tail: BirthNode,
1963 {
1964 }
1965
1966 impl BirthNode for Never {}
1967
1968 pub trait ChildPosition {}
1969 pub trait ChildProduct {}
1970
1971 pub trait ChildOccurrenceDescriptor {}
1972
1973 impl ChildOccurrenceDescriptor for DeclaredChildOccurrence {}
1974
1975 impl<Position> ChildOccurrenceDescriptor for StructuralChildOccurrence<Position> {}
1976
1977 pub trait OccurrenceResolution<Parent: Behavior, Occurrence> {}
1978
1979 impl<Parent, Occurrence> OccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1980 where
1981 Parent: Behavior,
1982 Occurrence: ChildRole<Parent>,
1983 {
1984 }
1985
1986 impl<Parent: Behavior> OccurrenceResolution<Parent, ChildHead>
1987 for StructuralChildOccurrence<ChildHead>
1988 {
1989 }
1990
1991 impl<Parent: Behavior, Position> OccurrenceResolution<Parent, ChildTail<Position>>
1992 for StructuralChildOccurrence<ChildTail<Position>>
1993 {
1994 }
1995
1996 pub trait ResolveDescriptor<Emitter: Behavior, Occurrence> {}
1997
1998 impl<Emitter, Occurrence, Position> ResolveDescriptor<Emitter, Occurrence>
1999 for StructuralChildOccurrence<Position>
2000 where
2001 Emitter: Behavior,
2002 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
2003 {
2004 }
2005
2006 impl<Emitter, Occurrence> ResolveDescriptor<Emitter, Occurrence> for DeclaredChildOccurrence
2007 where
2008 Emitter: Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol>
2009 + BehaviorBase,
2010 Emitter::Base: Behavior,
2011 Occurrence: ChildRole<Emitter::Base>,
2012 <Emitter::Birth as BirthMode>::Child:
2013 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
2014 Occurrence::Position:
2015 super::ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
2016 {
2017 }
2018
2019 pub trait ResolveChildOccurrence<Occurrence> {}
2020
2021 impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
2022 where
2023 Emitter: Behavior + BehaviorBase,
2024 Emitter::Base: Behavior,
2025 Occurrence: ChildOccurrence<Emitter::Base>,
2026 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
2027 {
2028 }
2029}
2030
2031#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2033pub struct NoChildren;
2034
2035impl sealed::ChildProduct for NoChildren {}
2036
2037pub struct ChildCons<A: Address, C, Earlier> {
2039 creation: CreateChild<A, C>,
2040 earlier: Earlier,
2041}
2042
2043impl<A: Address, C, Earlier> sealed::ChildProduct for ChildCons<A, C, Earlier> {}
2044
2045pub struct Children<A: Address, Product = NoChildren> {
2051 product: Product,
2052 address: PhantomData<fn() -> A>,
2053}
2054
2055pub trait ChildProduct<A: Address>: sealed::ChildProduct + Sized {
2057 type Choice: BirthNodeAppend<Never>;
2059
2060 #[doc(hidden)]
2061 fn stage(self) -> Vec<CreateChild<A, Self::Choice>>;
2062}
2063
2064impl<A: Address> ChildProduct<A> for NoChildren {
2065 type Choice = Never;
2066
2067 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
2068 Vec::new()
2069 }
2070}
2071
2072impl<A, C, Earlier> ChildProduct<A> for ChildCons<A, C, Earlier>
2073where
2074 A: Address,
2075 C: Behavior,
2076 C::Protocol: Protocol<Addr = A>,
2077 Earlier: ChildProduct<A>,
2078{
2079 type Choice = ChildChoice<C, Earlier::Choice>;
2080
2081 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
2082 let earlier = self.earlier.stage();
2083 let mut creates = earlier
2084 .into_iter()
2085 .map(|creation| {
2086 let (id, child, kind) = creation.into_parts();
2087 CreateChild::from_parts(id, ChildChoice::Tail(child), kind)
2088 })
2089 .collect::<Vec<_>>();
2090 let (id, child, kind) = self.creation.into_parts();
2091 creates.push(CreateChild::from_parts(id, ChildChoice::Head(child), kind));
2092 creates
2093 }
2094}
2095
2096impl<A: Address> Children<A, NoChildren> {
2097 #[must_use]
2099 pub const fn new() -> Self {
2100 Self {
2101 product: NoChildren,
2102 address: PhantomData,
2103 }
2104 }
2105}
2106
2107impl<A: Address> Default for Children<A, NoChildren> {
2108 fn default() -> Self {
2109 Self::new()
2110 }
2111}
2112
2113impl<A: Address, Product> Children<A, Product> {
2114 #[must_use]
2116 pub fn create<C>(self, creation: CreateChild<A, C>) -> Children<A, ChildCons<A, C, Product>>
2117 where
2118 C: Behavior,
2119 C::Protocol: Protocol<Addr = A>,
2120 {
2121 Children {
2122 product: ChildCons {
2123 creation,
2124 earlier: self.product,
2125 },
2126 address: PhantomData,
2127 }
2128 }
2129
2130 #[must_use]
2132 pub fn child<C>(self, id: CreationId, child: C) -> Children<A, ChildCons<A, C, Product>>
2133 where
2134 C: Behavior,
2135 C::Protocol: Protocol<Addr = A>,
2136 {
2137 self.create(CreateChild::birth(id, child))
2138 }
2139}
2140
2141impl<A, Product> Children<A, Product>
2142where
2143 A: Address,
2144 Product: ChildProduct<A>,
2145{
2146 #[must_use]
2148 pub fn into_creates(self) -> Creations<CreateChild<A, Product::Choice>> {
2149 Creations::from_items(self.product.stage())
2150 }
2151}
2152
2153impl<A, Occurrence, Head, Tail> ChildCreationProduct<A, Occurrence> for ChildChoice<Head, Tail>
2154where
2155 A: EndpointAddress,
2156 Head: Behavior,
2157 Head::Protocol: Protocol<Addr = A>,
2158 Tail: ChildCreationProduct<A, ChildTail<Occurrence>>,
2159{
2160 type Result = ChildChoice<
2161 ChildCreationOutcome<Head, Occurrence>,
2162 <Tail as ChildCreationProduct<A, ChildTail<Occurrence>>>::Result,
2163 >;
2164}
2165
2166impl<A, Occurrence, Head, Tail, Host> CreateSelectedChild<A, Occurrence, Host>
2167 for ChildChoice<Head, Tail>
2168where
2169 A: EndpointAddress,
2170 A::Nonce: Send,
2171 Head: Behavior + Send,
2172 Head::Protocol: Protocol<Addr = A>,
2173 Tail: CreateSelectedChild<A, ChildTail<Occurrence>, Host> + Send,
2174 Host: EstablishChild<Occurrence, Head> + Send,
2175{
2176 async fn dispatch_birth_at(
2177 self,
2178 id: CreationId,
2179 route: A::Nonce,
2180 kind: CreationKind,
2181 host: &mut Host,
2182 ) -> ItemSettlement<
2183 RoutedCreation<A, Self>,
2184 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2185 CreationRejection,
2186 Never,
2187 > {
2188 match self {
2189 Self::Head(child) => {
2190 let creation = RoutedCreation::new(CreateChild::from_parts(id, child, kind), route);
2191 match host.establish_child(creation).await {
2192 ItemSettlement::Accepted(receipt) => {
2193 ItemSettlement::Accepted(ChildChoice::Head(receipt))
2194 }
2195 ItemSettlement::Rejected { item, reason } => {
2196 let (creation, route) = item.into_parts();
2197 let (id, child, kind) = creation.into_parts();
2198 ItemSettlement::Rejected {
2199 item: RoutedCreation::new(
2200 CreateChild::from_parts(id, Self::Head(child), kind),
2201 route,
2202 ),
2203 reason,
2204 }
2205 }
2206 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2207 ItemSettlement::Corrupt { item, fault } => {
2208 let (creation, route) = item.into_parts();
2209 let (id, child, kind) = creation.into_parts();
2210 ItemSettlement::Corrupt {
2211 item: RoutedCreation::new(
2212 CreateChild::from_parts(id, Self::Head(child), kind),
2213 route,
2214 ),
2215 fault,
2216 }
2217 }
2218 }
2219 }
2220 Self::Tail(tail) => match tail.dispatch_birth_at(id, route, kind, host).await {
2221 ItemSettlement::Accepted(receipt) => {
2222 ItemSettlement::Accepted(ChildChoice::Tail(receipt))
2223 }
2224 ItemSettlement::Rejected { item, reason } => {
2225 let (creation, route) = item.into_parts();
2226 let (id, child, kind) = creation.into_parts();
2227 ItemSettlement::Rejected {
2228 item: RoutedCreation::new(
2229 CreateChild::from_parts(id, Self::Tail(child), kind),
2230 route,
2231 ),
2232 reason,
2233 }
2234 }
2235 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2236 ItemSettlement::Corrupt { item, fault } => {
2237 let (creation, route) = item.into_parts();
2238 let (id, child, kind) = creation.into_parts();
2239 ItemSettlement::Corrupt {
2240 item: RoutedCreation::new(
2241 CreateChild::from_parts(id, Self::Tail(child), kind),
2242 route,
2243 ),
2244 fault,
2245 }
2246 }
2247 },
2248 }
2249 }
2250}
2251
2252impl<A, Occurrence> ChildCreationProduct<A, Occurrence> for Never
2253where
2254 A: Address,
2255{
2256 type Result = Never;
2257}
2258
2259impl<A, Occurrence, Host> CreateSelectedChild<A, Occurrence, Host> for Never
2260where
2261 A: Address,
2262{
2263 fn dispatch_birth_at(
2264 self,
2265 _id: CreationId,
2266 _route: A::Nonce,
2267 _kind: CreationKind,
2268 _host: &mut Host,
2269 ) -> impl Future<
2270 Output = ItemSettlement<
2271 RoutedCreation<A, Self>,
2272 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2273 CreationRejection,
2274 Never,
2275 >,
2276 > + Send {
2277 async move { match self {} }
2278 }
2279}
2280
2281impl<A, Occurrence, C> ChildCreationProduct<A, Occurrence> for C
2282where
2283 A: EndpointAddress,
2284 C: Behavior,
2285 C::Protocol: Protocol<Addr = A>,
2286{
2287 type Result = ChildCreationOutcome<C, Occurrence>;
2288}
2289
2290impl<A, Occurrence, C, Host> CreateSelectedChild<A, Occurrence, Host> for C
2291where
2292 A: EndpointAddress,
2293 C: Behavior,
2294 C::Protocol: Protocol<Addr = A>,
2295 Host: EstablishChild<Occurrence, C>,
2296{
2297 fn dispatch_birth_at(
2298 self,
2299 id: CreationId,
2300 route: A::Nonce,
2301 kind: CreationKind,
2302 host: &mut Host,
2303 ) -> impl Future<
2304 Output = ItemSettlement<
2305 RoutedCreation<A, Self>,
2306 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2307 CreationRejection,
2308 Never,
2309 >,
2310 > + Send {
2311 host.establish_child(RoutedCreation::new(
2312 CreateChild::from_parts(id, self, kind),
2313 route,
2314 ))
2315 }
2316}
2317
2318pub trait BirthMode {
2320 type Child;
2321}
2322
2323pub struct NoBirthProtocols;
2325
2326pub struct BirthProtocol<P: Protocol, Tail> {
2328 protocol: PhantomData<fn() -> P>,
2329 tail: PhantomData<fn() -> Tail>,
2330}
2331
2332pub struct BirthProtocolHead;
2334
2335pub struct BirthProtocolTail<Position>(PhantomData<fn() -> Position>);
2337
2338pub trait BirthProtocolAt<P: Protocol, Position> {}
2340
2341impl<P: Protocol, Tail> BirthProtocolAt<P, BirthProtocolHead> for BirthProtocol<P, Tail> {}
2342
2343impl<Head, Tail, P, Position> BirthProtocolAt<P, BirthProtocolTail<Position>>
2344 for BirthProtocol<Head, Tail>
2345where
2346 Head: Protocol,
2347 P: Protocol,
2348 Tail: BirthProtocolAt<P, Position>,
2349{
2350}
2351
2352pub trait BirthProtocolProduct {
2354 type Append<Tail: BirthProtocolProduct>: BirthProtocolProduct;
2355}
2356
2357impl BirthProtocolProduct for NoBirthProtocols {
2358 type Append<Tail: BirthProtocolProduct> = Tail;
2359}
2360
2361impl<P, Rest> BirthProtocolProduct for BirthProtocol<P, Rest>
2362where
2363 P: Protocol,
2364 Rest: BirthProtocolProduct,
2365{
2366 type Append<Tail: BirthProtocolProduct> = BirthProtocol<P, Rest::Append<Tail>>;
2367}
2368
2369pub trait BirthProtocols: Behavior {
2375 type Protocols: BirthProtocolProduct;
2376}
2377
2378impl<B> BirthProtocols for B
2379where
2380 B: Behavior,
2381 B::Birth: BirthModeProtocols,
2382{
2383 type Protocols = BirthProtocol<B::Protocol, <B::Birth as BirthModeProtocols>::Protocols>;
2384}
2385
2386#[doc(hidden)]
2387pub trait BirthModeProtocols {
2388 type Protocols: BirthProtocolProduct;
2389}
2390
2391impl<M> BirthModeProtocols for M
2392where
2393 M: BirthMode,
2394 M::Child: BirthNodeProtocols,
2395{
2396 type Protocols = <M::Child as BirthNodeProtocols>::Protocols;
2397}
2398
2399#[doc(hidden)]
2400pub trait BirthNodeProtocols {
2401 type Protocols: BirthProtocolProduct;
2402}
2403
2404impl<B> BirthNodeProtocols for B
2405where
2406 B: BirthProtocols,
2407{
2408 type Protocols = B::Protocols;
2409}
2410
2411impl<Head, Tail> BirthNodeProtocols for ChildChoice<Head, Tail>
2412where
2413 Head: BirthNodeProtocols,
2414 Tail: BirthNodeProtocols,
2415{
2416 type Protocols = <Head::Protocols as BirthProtocolProduct>::Append<Tail::Protocols>;
2417}
2418
2419impl BirthNodeProtocols for Never {
2420 type Protocols = NoBirthProtocols;
2421}
2422
2423#[doc(hidden)]
2428pub trait BirthNodeLogicalHosts {
2429 type LogicalHosts: BirthProtocolProduct;
2430}
2431
2432impl<B> BirthNodeLogicalHosts for B
2433where
2434 B: crate::LogicalHostRequirements,
2435{
2436 type LogicalHosts = B::LogicalHosts;
2437}
2438
2439impl<Head, Tail> BirthNodeLogicalHosts for ChildChoice<Head, Tail>
2440where
2441 Head: BirthNodeLogicalHosts,
2442 Tail: BirthNodeLogicalHosts,
2443{
2444 type LogicalHosts = <Head::LogicalHosts as BirthProtocolProduct>::Append<Tail::LogicalHosts>;
2445}
2446
2447impl BirthNodeLogicalHosts for Never {
2448 type LogicalHosts = NoBirthProtocols;
2449}
2450
2451#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2453pub struct NoBirths;
2454
2455impl BirthMode for NoBirths {
2456 type Child = Never;
2457}
2458
2459#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2461pub struct Births<C>(PhantomData<fn() -> C>);
2462
2463impl<C> BirthMode for Births<C> {
2464 type Child = C;
2465}
2466
2467#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2475pub struct RetirementBirths<C>(PhantomData<fn() -> C>);
2476
2477impl<C> BirthMode for RetirementBirths<C> {
2478 type Child = C;
2479}
2480
2481#[cfg(test)]
2482mod tests {
2483 use super::*;
2484 use crate::{
2485 Actions, BehaviorActed, ChildInputIngress, EventLayer, Interpretation, NoBirths, User,
2486 };
2487
2488 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2489 struct TestAddr(u64);
2490
2491 impl Address for TestAddr {
2492 type Nonce = u64;
2493 }
2494
2495 struct TestEndpoint<P>(PhantomData<fn() -> P>);
2496
2497 impl<P> Clone for TestEndpoint<P> {
2498 fn clone(&self) -> Self {
2499 *self
2500 }
2501 }
2502
2503 impl<P> Copy for TestEndpoint<P> {}
2504
2505 struct TestInstalled<B: Behavior> {
2506 endpoint: TestEndpoint<B::Protocol>,
2507 control: std::sync::mpsc::Sender<B::Event>,
2508 }
2509
2510 impl<B: Behavior> Clone for TestInstalled<B> {
2511 fn clone(&self) -> Self {
2512 Self {
2513 endpoint: self.endpoint,
2514 control: self.control.clone(),
2515 }
2516 }
2517 }
2518
2519 impl EndpointAddress for TestAddr {
2520 type Established<P>
2521 = TestEndpoint<P>
2522 where
2523 P: Protocol<Addr = Self>;
2524
2525 type Installed<B>
2526 = TestInstalled<B>
2527 where
2528 B: Behavior<Protocol: Protocol<Addr = Self>>;
2529
2530 fn recipient<B>(installed: &Self::Installed<B>) -> Self::Established<B::Protocol>
2531 where
2532 B: Behavior<Protocol: Protocol<Addr = Self>>,
2533 {
2534 installed.endpoint
2535 }
2536 }
2537
2538 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2539 struct Child;
2540
2541 struct SharedProtocol;
2542
2543 impl behavior::Protocol for SharedProtocol {
2544 type Addr = TestAddr;
2545 type Msg = u8;
2546 }
2547
2548 struct Primary;
2549 struct Fallback;
2550
2551 macro_rules! shared_protocol_behavior {
2552 ($behavior:ty, $birth:ty) => {
2553 impl Behavior for $behavior {
2554 type Protocol = SharedProtocol;
2555 type Event = User<TestAddr, u8>;
2556 type Sends = Vec<Never>;
2557 type Ph = Never;
2558 type Error = Never;
2559 type Birth = $birth;
2560
2561 fn transition(
2562 &mut self,
2563 _: crate::ActiveTurn,
2564 _: Self::Event,
2565 ) -> BehaviorActed<Self> {
2566 Ok(Actions::cont())
2567 }
2568 }
2569 };
2570 }
2571
2572 shared_protocol_behavior!(Primary, Births<Child>);
2573 shared_protocol_behavior!(Fallback, NoBirths);
2574
2575 impl behavior::Protocol for Child {
2576 type Addr = TestAddr;
2577 type Msg = u8;
2578 }
2579
2580 impl Behavior for Child {
2581 type Protocol = Self;
2582 type Event = User<TestAddr, u8>;
2583 type Sends = Vec<Never>;
2584 type Ph = Never;
2585 type Error = Never;
2586 type Birth = NoBirths;
2587
2588 fn transition(&mut self, _: crate::ActiveTurn, _: Self::Event) -> BehaviorActed<Self> {
2589 Ok(Actions::cont())
2590 }
2591 }
2592
2593 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2594 enum ChildPlan {
2595 CreateChild,
2596 RejectBeforeTransfer,
2597 }
2598
2599 struct RecordingHost {
2600 calls: usize,
2601 observed: Vec<(CreationId, u64, CreationKind)>,
2602 plan: ChildPlan,
2603 control_receivers: Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2604 }
2605
2606 #[derive(Debug, PartialEq, Eq)]
2607 enum SharedCreation {
2608 Primary(CreationId, u64),
2609 Fallback(CreationId, u64),
2610 }
2611
2612 #[derive(Default)]
2613 struct SharedProtocolHost(
2614 Vec<SharedCreation>,
2615 Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2616 );
2617
2618 impl EstablishChild<ChildHead, Primary> for SharedProtocolHost {
2619 async fn establish_child(
2620 &mut self,
2621 creation: RoutedCreation<TestAddr, Primary>,
2622 ) -> ItemSettlement<
2623 RoutedCreation<TestAddr, Primary>,
2624 ChildCreationOutcome<Primary, ChildHead>,
2625 CreationRejection,
2626 Never,
2627 > {
2628 let id = creation.id();
2629 let kind = creation.kind();
2630 let route = creation.route();
2631 let (creation, _) = creation.into_parts();
2632 let (_, _child, _) = creation.into_parts();
2633 self.0.push(SharedCreation::Primary(id, route));
2634 let (control, receiver) = std::sync::mpsc::channel();
2635 self.1.push(receiver);
2636 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2637 id,
2638 kind,
2639 EstablishedActor::issued(TestInstalled {
2640 endpoint: TestEndpoint(PhantomData),
2641 control,
2642 }),
2643 )))
2644 }
2645 }
2646
2647 impl EstablishChild<ChildTail<ChildHead>, Fallback> for SharedProtocolHost {
2648 async fn establish_child(
2649 &mut self,
2650 creation: RoutedCreation<TestAddr, Fallback>,
2651 ) -> ItemSettlement<
2652 RoutedCreation<TestAddr, Fallback>,
2653 ChildCreationOutcome<Fallback, ChildTail<ChildHead>>,
2654 CreationRejection,
2655 Never,
2656 > {
2657 let id = creation.id();
2658 let kind = creation.kind();
2659 let route = creation.route();
2660 let (creation, _) = creation.into_parts();
2661 let (_, _child, _) = creation.into_parts();
2662 self.0.push(SharedCreation::Fallback(id, route));
2663 let (control, receiver) = std::sync::mpsc::channel();
2664 self.1.push(receiver);
2665 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2666 id,
2667 kind,
2668 EstablishedActor::issued(TestInstalled {
2669 endpoint: TestEndpoint(PhantomData),
2670 control,
2671 }),
2672 )))
2673 }
2674 }
2675
2676 impl EstablishChild<ChildHead, Child> for RecordingHost {
2677 async fn establish_child(
2678 &mut self,
2679 creation: RoutedCreation<TestAddr, Child>,
2680 ) -> ItemSettlement<
2681 RoutedCreation<TestAddr, Child>,
2682 ChildCreationOutcome<Child, ChildHead>,
2683 CreationRejection,
2684 Never,
2685 > {
2686 self.calls += 1;
2687 self.observed
2688 .push((creation.id(), creation.route(), creation.kind()));
2689 match self.plan {
2690 ChildPlan::CreateChild => {
2691 let id = creation.id();
2692 let kind = creation.kind();
2693 let (creation, _) = creation.into_parts();
2694 let (_, _child, _) = creation.into_parts();
2695 let (control, receiver) = std::sync::mpsc::channel();
2696 self.control_receivers.push(receiver);
2697 ItemSettlement::Accepted(ChildCreationOutcome::Established(
2698 CommittedChild::new(
2699 id,
2700 kind,
2701 EstablishedActor::issued(TestInstalled {
2702 endpoint: TestEndpoint(PhantomData),
2703 control,
2704 }),
2705 ),
2706 ))
2707 }
2708 ChildPlan::RejectBeforeTransfer => ItemSettlement::Rejected {
2709 item: creation,
2710 reason: CreationRejection::EnvironmentFailed,
2711 },
2712 }
2713 }
2714 }
2715
2716 fn host(plan: ChildPlan) -> RecordingHost {
2717 RecordingHost {
2718 calls: 0,
2719 observed: Vec::new(),
2720 plan,
2721 control_receivers: Vec::new(),
2722 }
2723 }
2724
2725 fn assert_send<T: Send>(_: &T) {}
2726
2727 #[test]
2728 fn empty_child_product_stages_no_creations() {
2729 let creations = <NoChildren as ChildProduct<TestAddr>>::stage(NoChildren);
2730 assert!(creations.is_empty());
2731 }
2732
2733 #[test]
2734 fn creation_values_preserve_ids_order_and_debug_identity() {
2735 let mut sequence = CreationSequence::new();
2736 let first = sequence.issue().expect("the first creation ID exists");
2737 let second = sequence.issue().expect("the second creation ID exists");
2738 assert_eq!(first.get(), 1);
2739 assert_eq!(second.get(), 2);
2740
2741 let first_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2742 let same_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2743 let second_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(second);
2744 assert_eq!(first_correlation, same_correlation);
2745 assert_ne!(first_correlation, second_correlation);
2746 assert_eq!(
2747 format!("{first_correlation:?}"),
2748 "CreationCorrelation(CreationId(1))"
2749 );
2750
2751 let mut creations = Creations::one(1_u8);
2752 creations.extend([2, 3]);
2753 assert_eq!(creations.len(), 3);
2754 assert!(!creations.is_empty());
2755 assert_eq!(creations.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
2756 let borrowed = (&creations).into_iter().copied().collect::<Vec<_>>();
2757 assert_eq!(borrowed, [1, 2, 3]);
2758
2759 let collected: Creations<_> = [4_u8, 5].into_iter().collect();
2760 assert_eq!(collected.len(), 2);
2761 let collected_values = collected.into_iter().collect::<Vec<_>>();
2762 assert_eq!(collected_values, [4, 5]);
2763
2764 let returned = ChildCreationSettled::<Child, ChildHead>::new(SettledItem::Unattempted(
2765 RoutedCreation::new(CreateChild::birth(first, Child), 17),
2766 ));
2767 assert_eq!(format!("{returned:?}"), "ChildCreationSettled { .. }");
2768 }
2769
2770 #[tokio::test]
2771 async fn concrete_child_dispatches_once_with_exact_creation_and_route() {
2772 let mut sequence = CreationSequence::new();
2773 let previous = sequence.issue().expect("the previous ID exists");
2774 let id = sequence.issue().expect("the replacement ID exists");
2775 let mut host = host(ChildPlan::CreateChild);
2776 let kind = CreationKind::replacement(previous);
2777 let future = Child.dispatch_birth(id, 17, kind, &mut host);
2778 assert_send(&future);
2779 let result = future.await;
2780
2781 let ItemSettlement::Accepted(ChildCreationOutcome::Established(established)) = result
2782 else {
2783 panic!("expected the child to be created");
2784 };
2785 assert_eq!(established.id(), id);
2786 assert_eq!(host.calls, 1);
2787 assert_eq!(host.observed, [(id, 17, kind)]);
2788 }
2789
2790 #[tokio::test]
2791 async fn concrete_child_returns_the_exact_rejected_creation_without_retry() {
2792 let mut sequence = CreationSequence::new();
2793 let previous = sequence.issue().expect("the previous ID exists");
2794 let id = sequence.issue().expect("the replacement ID exists");
2795 let mut host = host(ChildPlan::RejectBeforeTransfer);
2796 let kind = CreationKind::replacement(previous);
2797 let future = Child.dispatch_birth(id, 23, kind, &mut host);
2798 assert_send(&future);
2799 let result = future.await;
2800
2801 let ItemSettlement::Rejected { item, reason } = result else {
2802 panic!("expected refusal before child ownership transfer");
2803 };
2804 assert_eq!(
2805 item,
2806 RoutedCreation::new(CreateChild::replacement(id, previous, Child), 23)
2807 );
2808 assert_eq!(reason, CreationRejection::EnvironmentFailed);
2809 assert_eq!(host.calls, 1);
2810 assert_eq!(host.observed, [(id, 23, kind)]);
2811 }
2812
2813 #[tokio::test]
2814 async fn distinct_child_alternatives_preserve_one_canonical_protocol_identity() {
2815 type Alternatives = ChildChoice<Primary, ChildChoice<Fallback, Never>>;
2816
2817 fn requires_shared_protocol<C: Behavior<Protocol = SharedProtocol>>() {}
2818 requires_shared_protocol::<Primary>();
2819 requires_shared_protocol::<Fallback>();
2820
2821 let mut sequence = CreationSequence::new();
2822 let primary_id = sequence.issue().expect("the primary ID exists");
2823 let fallback_id = sequence.issue().expect("the fallback ID exists");
2824 let mut host = SharedProtocolHost::default();
2825 let primary = Alternatives::Head(Primary)
2826 .dispatch_birth(primary_id, 11, CreationKind::Birth, &mut host)
2827 .await;
2828 let fallback = Alternatives::Tail(ChildChoice::Head(Fallback))
2829 .dispatch_birth(fallback_id, 17, CreationKind::Birth, &mut host)
2830 .await;
2831
2832 let ItemSettlement::Accepted(ChildChoice::Head(ChildCreationOutcome::Established(primary))) =
2833 primary
2834 else {
2835 panic!("expected the primary child result");
2836 };
2837 assert_eq!(primary.id(), primary_id);
2838 let ItemSettlement::Accepted(ChildChoice::Tail(ChildChoice::Head(
2839 ChildCreationOutcome::Established(fallback),
2840 ))) = fallback
2841 else {
2842 panic!("expected the fallback child result");
2843 };
2844 assert_eq!(fallback.id(), fallback_id);
2845
2846 assert_eq!(
2847 host.0,
2848 [
2849 SharedCreation::Primary(primary_id, 11),
2850 SharedCreation::Fallback(fallback_id, 17),
2851 ]
2852 );
2853 }
2854
2855 #[test]
2856 fn birth_protocol_projection_recurses_without_inspecting_send_lanes() {
2857 type Protocols = <Primary as BirthProtocols>::Protocols;
2858 type Expected = BirthProtocol<SharedProtocol, BirthProtocol<Child, NoBirthProtocols>>;
2859
2860 trait Same<T> {}
2861 impl<T> Same<T> for T {}
2862 fn exact<T: Same<Expected>>() {}
2863 exact::<Protocols>();
2864 }
2865 fn child_request_loan_is_affine<Item, Observation>(
2866 request: Item,
2867 duplicate: Item,
2868 reason: Item::Rejection,
2869 observe: impl Fn(&Item) -> Observation,
2870 ) where
2871 Item: ActionItem<
2872 Custody = (Option<Item>, Option<<Item as ActionItem>::Reply>),
2873 Reply = ItemSettlement<
2874 Item,
2875 <Item as ActionItem>::Accepted,
2876 <Item as ActionItem>::Rejection,
2877 <Item as ActionItem>::Prerequisite,
2878 >,
2879 > + 'static,
2880 for<'a> Item: ActionItem<Input<'a> = &'a mut Option<Item>>,
2881 Item::Rejection: Copy + PartialEq + core::fmt::Debug,
2882 Observation: PartialEq + core::fmt::Debug,
2883 {
2884 let expected = observe(&request);
2885 let mut progress = Some(InterpretationProgress::Original(request));
2886 Item::prepare_interpretation(&mut progress);
2887 Item::prepare_interpretation(&mut progress);
2888 let Some(InterpretationProgress::Interpreting(custody)) = &mut progress else {
2889 panic!("preparation must preserve the real request in outside custody");
2890 };
2891 let (input, reply) = Item::interpretation_input(custody)
2892 .expect("one unreplied request must loan its complete input");
2893 let request = input.take().expect("the loan owns the complete request");
2894 let observed = observe(&request);
2895 assert_eq!(
2896 observed, expected,
2897 "the host loan must preserve the complete request"
2898 );
2899 *reply = Some(ItemSettlement::Rejected {
2900 item: request,
2901 reason,
2902 });
2903 let replied = Item::interpretation_input(custody);
2904 assert!(
2905 replied.is_none(),
2906 "a replied request must not be loaned again"
2907 );
2908 custody.0 = Some(duplicate);
2909 let duplicate_loan = Item::interpretation_input(custody);
2910 assert!(
2911 duplicate_loan.is_none(),
2912 "a reply denies reentry even if input is retained"
2913 );
2914 let duplicate = custody
2915 .0
2916 .take()
2917 .expect("the duplicate remains outside-owned");
2918 drop(duplicate);
2919 Item::finish_interpretation(&mut progress);
2920 Item::prepare_interpretation(&mut progress);
2921 Item::finish_interpretation(&mut progress);
2922 match progress {
2923 Some(InterpretationProgress::Completed(Interpretation::Complete(
2924 ItemSettlement::Rejected {
2925 item,
2926 reason: returned_reason,
2927 },
2928 ))) => {
2929 let observed = observe(&item);
2930 assert_eq!(
2931 (observed, returned_reason),
2932 (expected, reason),
2933 "replay must preserve the complete rejected request and reason"
2934 );
2935 }
2936 _ => panic!("completed ownership must survive preparation and finalization replay"),
2937 }
2938 let mut empty = (None, None);
2939 let missing = Item::interpretation_input(&mut empty);
2940 assert!(
2941 missing.is_none(),
2942 "missing input must never expose a host loan"
2943 );
2944 }
2945
2946 impl ChildInputIngress<ChildHead, u8> for User<TestAddr, u8> {
2947 fn child_input(input: u8) -> Self {
2948 User::new(TestAddr(7), input)
2949 }
2950 fn recover_child_input(event: Self) -> Result<u8, Self> {
2951 Ok(event.message)
2952 }
2953 }
2954
2955 type ParentInputWithOuterNotice = EventLayer<Box<str>, EventLayer<u64, User<TestAddr, u8>>>;
2956 type ParentInputWithInnerNotice = EventLayer<u64, EventLayer<Box<str>, User<TestAddr, u8>>>;
2957
2958 #[test]
2959 fn private_input_lifting_preserves_control_in_both_layer_orders() {
2960 let event =
2961 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::child_input(43);
2962 let EventLayer::Inner(EventLayer::Inner(original)) = &event else {
2963 panic!("private input must reach its exact inner user lane");
2964 };
2965 assert_eq!(original, &User::new(TestAddr(7), 43));
2966 let returned =
2967 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
2968 event,
2969 );
2970 assert_eq!(returned, Ok(43));
2971
2972 let event =
2973 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::child_input(47);
2974 let EventLayer::Inner(EventLayer::Inner(original)) = &event else {
2975 panic!("private input must reach the same lane after reordering");
2976 };
2977 assert_eq!(original, &User::new(TestAddr(7), 47));
2978 let returned =
2979 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
2980 event,
2981 );
2982 assert_eq!(returned, Ok(47));
2983 }
2984
2985 #[test]
2986 fn private_input_recovery_returns_each_foreign_owned_lane() {
2987 let notice = Box::<str>::from("outer notice");
2988 let allocation = notice.as_ptr();
2989 let event = ParentInputWithOuterNotice::Owned(notice);
2990 let returned =
2991 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
2992 event,
2993 );
2994 let Err(EventLayer::Owned(returned)) = returned else {
2995 panic!("the outer notice must return in its original lane");
2996 };
2997 assert_eq!(returned.as_ptr(), allocation);
2998 assert_eq!(&*returned, "outer notice");
2999
3000 let event = ParentInputWithOuterNotice::Inner(EventLayer::Owned(37));
3001 let returned =
3002 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
3003 event,
3004 );
3005 assert_eq!(returned, Err(EventLayer::Inner(EventLayer::Owned(37))));
3006
3007 let event = ParentInputWithInnerNotice::Owned(41);
3008 let returned =
3009 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
3010 event,
3011 );
3012 assert_eq!(returned, Err(EventLayer::Owned(41)));
3013
3014 let notice = Box::<str>::from("inner notice");
3015 let allocation = notice.as_ptr();
3016 let event = ParentInputWithInnerNotice::Inner(EventLayer::Owned(notice));
3017 let returned =
3018 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
3019 event,
3020 );
3021 let Err(EventLayer::Inner(EventLayer::Owned(returned))) = returned else {
3022 panic!("the reordered inner notice must return in its original lane");
3023 };
3024 assert_eq!(returned.as_ptr(), allocation);
3025 assert_eq!(&*returned, "inner notice");
3026 }
3027
3028 #[test]
3029 fn child_delivery_custody_allows_one_complete_request_and_denies_replay() {
3030 let id = CreationSequence::new()
3031 .issue()
3032 .expect("the creation ID exists");
3033 let request = ChildDelivery::<SharedProtocol, ChildHead>::after(id, 41);
3034 child_request_loan_is_affine(
3035 request,
3036 ChildDelivery::<SharedProtocol, ChildHead>::after(id, 47),
3037 ChildDeliveryReason::ClosedRecipient,
3038 |request| (request.creation, request.message),
3039 );
3040 }
3041
3042 #[test]
3043 fn private_child_input_custody_allows_one_complete_request_and_denies_replay() {
3044 let id = CreationSequence::new()
3045 .issue()
3046 .expect("the creation ID exists");
3047 let request = ChildInput::<Child, ChildHead, u8, ChildHead>::after(id, 43);
3048 child_request_loan_is_affine(
3049 request,
3050 ChildInput::<Child, ChildHead, u8, ChildHead>::after(id, 47),
3051 ChildInputReason::ClosedControlLane,
3052 |request| (request.creation, request.input),
3053 );
3054 }
3055
3056 #[test]
3057 fn creation_route_custody_allows_one_complete_batch_and_denies_replay() {
3058 let id = CreationSequence::new()
3059 .issue()
3060 .expect("the creation ID exists");
3061 let request = Creations::one(CreateChild::<TestAddr, Child>::birth(id, Child));
3062 child_request_loan_is_affine(
3063 request,
3064 Creations::one(CreateChild::<TestAddr, Child>::birth(id, Child)),
3065 ChildNamespaceExhausted,
3066 |request| {
3067 request
3068 .iter()
3069 .map(|creation| (creation.id(), creation.kind(), *creation.child()))
3070 .collect::<Vec<_>>()
3071 },
3072 );
3073 }
3074}