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("the creation correlation is already recorded in this child occurrence")]
477 CorrelationAlreadyRecorded,
478 #[error("fresh allocation failed: {0}")]
480 Allocation(AllocationRejection),
481 #[error("child initialization failed")]
483 InitializationFailed,
484 #[error("the interpreter could not install and commit the child")]
486 EnvironmentFailed,
487}
488
489#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
491#[error("the creator child namespace is exhausted")]
492pub struct ChildNamespaceExhausted;
493
494impl<A, New> ActionItem for Creations<CreateChild<A, New>>
495where
496 A: Address,
497 A::Nonce: Send,
498 New: Send,
499{
500 type Custody = (Option<Self>, Option<Self::Reply>);
501 type Input<'a>
502 = &'a mut Option<Self>
503 where
504 Self: 'a;
505 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
506
507 fn prepare_interpretation(
508 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
509 ) {
510 prepare_item::<Self>(progress);
511 }
512 fn interpretation_input<'a>(
513 custody: &'a mut Self::Custody,
514 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
515 where
516 Self: 'a,
517 {
518 let (input, received) = custody;
519 if input.is_some() && received.is_none() {
520 Some((input, received))
521 } else {
522 None
523 }
524 }
525 fn finish_interpretation(
526 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
527 ) {
528 finish_item::<Self>(progress);
529 }
530
531 type Accepted = Creations<RoutedCreation<A, New>>;
532 type Rejection = ChildNamespaceExhausted;
533 type Prerequisite = Never;
534}
535
536pub struct CommittedChild<C, Occurrence>
540where
541 C: Behavior,
542 BehaviorAddr<C>: EndpointAddress,
543{
544 id: CreationId,
545 kind: CreationKind,
546 actor: EstablishedActor<C>,
547 occurrence: PhantomData<fn() -> Occurrence>,
548}
549
550impl<C, Occurrence> CommittedChild<C, Occurrence>
551where
552 C: Behavior,
553 BehaviorAddr<C>: EndpointAddress,
554{
555 #[must_use]
559 pub const fn new(id: CreationId, kind: CreationKind, actor: EstablishedActor<C>) -> Self {
560 Self {
561 id,
562 kind,
563 actor,
564 occurrence: PhantomData,
565 }
566 }
567
568 #[must_use]
569 pub const fn id(&self) -> CreationId {
570 self.id
571 }
572
573 #[must_use]
574 pub const fn kind(&self) -> CreationKind {
575 self.kind
576 }
577
578 #[must_use]
579 pub fn actor(&self) -> EstablishedActor<C> {
580 self.actor.clone()
581 }
582
583 #[must_use]
584 pub fn into_parts(self) -> (CreationId, CreationKind, EstablishedActor<C>) {
585 (self.id, self.kind, self.actor)
586 }
587}
588
589pub enum EstablishedCreation<C, Occurrence>
628where
629 C: Behavior,
630 BehaviorAddr<C>: EndpointAddress,
631{
632 Installed(CommittedChild<C, Occurrence>),
633 Rejected {
634 id: CreationId,
635 kind: CreationKind,
636 reason: CreationRejection,
637 occurrence: PhantomData<fn() -> Occurrence>,
638 },
639}
640
641impl<C, Occurrence> EstablishedCreation<C, Occurrence>
642where
643 C: Behavior,
644 BehaviorAddr<C>: EndpointAddress,
645{
646 #[must_use]
647 pub const fn installed(child: CommittedChild<C, Occurrence>) -> Self {
648 Self::Installed(child)
649 }
650
651 #[must_use]
652 pub const fn rejected(id: CreationId, kind: CreationKind, reason: CreationRejection) -> Self {
653 Self::Rejected {
654 id,
655 kind,
656 reason,
657 occurrence: PhantomData,
658 }
659 }
660
661 #[must_use]
662 pub const fn id(&self) -> CreationId {
663 match self {
664 Self::Installed(child) => child.id(),
665 Self::Rejected { id, .. } => *id,
666 }
667 }
668
669 #[must_use]
670 pub const fn kind(&self) -> CreationKind {
671 match self {
672 Self::Installed(child) => child.kind(),
673 Self::Rejected { kind, .. } => *kind,
674 }
675 }
676
677 pub fn into_recipient(self) -> Result<EstablishedRecipient<C::Protocol>, CreationRejection> {
683 match self {
684 Self::Installed(child) => Ok(child.into_parts().2.into_recipient()),
685 Self::Rejected { reason, .. } => Err(reason),
686 }
687 }
688
689 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, CreationRejection> {
696 match self {
697 Self::Installed(child) => Ok(child),
698 Self::Rejected { reason, .. } => Err(reason),
699 }
700 }
701}
702
703pub enum ChildCreationOutcome<C, Occurrence>
729where
730 C: Behavior,
731 BehaviorAddr<C>: EndpointAddress,
732{
733 Established(CommittedChild<C, Occurrence>),
735 Unavailable {
738 id: CreationId,
740 kind: CreationKind,
742 },
743 InitializationRejected {
745 creation: RoutedCreation<BehaviorAddr<C>, C>,
747 error: C::Error,
749 },
750 InitializationPanicked {
755 creation: RoutedCreation<BehaviorAddr<C>, C>,
757 },
758 HostRejected {
760 creation: RoutedCreation<BehaviorAddr<C>, C>,
762 initialization: Actions<BehaviorAddr<C>, C::Ph, C::Sends, C::Birth>,
764 reason: CreationRejection,
766 },
767}
768
769impl<C, Occurrence> ChildCreationOutcome<C, Occurrence>
770where
771 C: Behavior,
772 BehaviorAddr<C>: EndpointAddress,
773{
774 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, Self> {
784 match self {
785 Self::Established(child) => Ok(child),
786 other => Err(other),
787 }
788 }
789
790 pub fn into_actor(self) -> Result<EstablishedActor<C>, Self> {
795 self.into_committed().map(|child| child.into_parts().2)
796 }
797}
798
799#[must_use = "a child-creation settlement must be admitted or retained"]
807pub struct ChildCreationSettled<C, Occurrence>
808where
809 C: Behavior,
810 BehaviorAddr<C>: EndpointAddress,
811{
812 settlement: SettledItem<
813 RoutedCreation<BehaviorAddr<C>, C>,
814 ItemSettlement<
815 RoutedCreation<BehaviorAddr<C>, C>,
816 ChildCreationOutcome<C, Occurrence>,
817 CreationRejection,
818 Never,
819 >,
820 >,
821}
822
823impl<C, Occurrence> ChildCreationSettled<C, Occurrence>
824where
825 C: Behavior,
826 BehaviorAddr<C>: EndpointAddress,
827{
828 #[must_use]
829 pub const fn new(
830 settlement: SettledItem<
831 RoutedCreation<BehaviorAddr<C>, C>,
832 ItemSettlement<
833 RoutedCreation<BehaviorAddr<C>, C>,
834 ChildCreationOutcome<C, Occurrence>,
835 CreationRejection,
836 Never,
837 >,
838 >,
839 ) -> Self {
840 Self { settlement }
841 }
842
843 #[must_use]
845 pub fn into_settlement(
846 self,
847 ) -> SettledItem<
848 RoutedCreation<BehaviorAddr<C>, C>,
849 ItemSettlement<
850 RoutedCreation<BehaviorAddr<C>, C>,
851 ChildCreationOutcome<C, Occurrence>,
852 CreationRejection,
853 Never,
854 >,
855 > {
856 self.settlement
857 }
858}
859
860impl<C, Occurrence> core::fmt::Debug for ChildCreationSettled<C, Occurrence>
861where
862 C: Behavior,
863 BehaviorAddr<C>: EndpointAddress,
864{
865 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
866 formatter
867 .debug_struct("ChildCreationSettled")
868 .finish_non_exhaustive()
869 }
870}
871
872pub struct CreationCorrelation<P, Occurrence>
895where
896 P: Protocol,
897{
898 id: CreationId,
899 occurrence: PhantomData<fn() -> (P, Occurrence)>,
900}
901
902impl<P, Occurrence> CreationCorrelation<P, Occurrence>
903where
904 P: Protocol,
905{
906 #[must_use]
907 pub const fn new(id: CreationId) -> Self {
908 Self {
909 id,
910 occurrence: PhantomData,
911 }
912 }
913
914 #[must_use]
915 pub const fn id(self) -> CreationId {
916 self.id
917 }
918}
919
920impl<P, Occurrence> Copy for CreationCorrelation<P, Occurrence> where P: Protocol {}
921
922impl<P, Occurrence> Clone for CreationCorrelation<P, Occurrence>
923where
924 P: Protocol,
925{
926 fn clone(&self) -> Self {
927 *self
928 }
929}
930
931impl<P, Occurrence> core::fmt::Debug for CreationCorrelation<P, Occurrence>
932where
933 P: Protocol,
934{
935 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
936 formatter
937 .debug_tuple("CreationCorrelation")
938 .field(&self.id)
939 .finish()
940 }
941}
942
943impl<P, Occurrence> PartialEq for CreationCorrelation<P, Occurrence>
944where
945 P: Protocol,
946{
947 fn eq(&self, other: &Self) -> bool {
948 self.id == other.id
949 }
950}
951
952impl<P, Occurrence> Eq for CreationCorrelation<P, Occurrence> where P: Protocol {}
953
954pub struct ChildDelivery<P, Occurrence>
961where
962 P: Protocol,
963{
964 pub creation: CreationId,
965 pub message: P::Msg,
966 occurrence: PhantomData<fn() -> Occurrence>,
967}
968
969pub struct ChildInput<Child, Source, Input, Occurrence>
982where
983 Child: Behavior,
984{
985 pub creation: CreationId,
987 pub input: Input,
989 marker: PhantomData<fn() -> (Child, Source, Occurrence)>,
990}
991
992#[derive(Clone, Copy, Debug, Eq, PartialEq)]
994pub enum ChildDeliveryReason {
995 MissingBinding,
996 ClosedRecipient,
997}
998
999#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1001pub enum ChildInputReason {
1002 MissingBinding,
1003 ClosedControlLane,
1004}
1005
1006#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1013pub struct ChildReport<R> {
1014 pub child: CreationId,
1016 pub report: R,
1018}
1019
1020impl<R> ChildReport<R> {
1021 #[must_use]
1023 pub const fn new(child: CreationId, report: R) -> Self {
1024 Self { child, report }
1025 }
1026}
1027
1028impl<R> From<(CreationId, crate::ReportToParent<R>)> for ChildReport<R> {
1029 fn from((child, request): (CreationId, crate::ReportToParent<R>)) -> Self {
1030 Self::new(child, request.into_inner())
1031 }
1032}
1033
1034impl<Child, Source, Input, Occurrence> ChildInput<Child, Source, Input, Occurrence>
1035where
1036 Child: Behavior,
1037 Child::Event: crate::ChildInputIngress<Source, Input>,
1038{
1039 #[must_use]
1041 pub const fn after(creation: CreationId, input: Input) -> Self {
1042 Self {
1043 creation,
1044 input,
1045 marker: PhantomData,
1046 }
1047 }
1048}
1049
1050impl<Child, Source, Input, Occurrence> Clone for ChildInput<Child, Source, Input, Occurrence>
1051where
1052 Child: Behavior,
1053 Input: Clone,
1054{
1055 fn clone(&self) -> Self {
1056 Self {
1057 creation: self.creation,
1058 input: self.input.clone(),
1059 marker: PhantomData,
1060 }
1061 }
1062}
1063
1064impl<P, Occurrence> ChildDelivery<P, Occurrence>
1065where
1066 P: Protocol,
1067{
1068 #[must_use]
1069 pub const fn after(creation: CreationId, message: P::Msg) -> Self {
1070 Self {
1071 creation,
1072 message,
1073 occurrence: PhantomData,
1074 }
1075 }
1076}
1077
1078impl<P, Occurrence> Clone for ChildDelivery<P, Occurrence>
1079where
1080 P: Protocol,
1081 P::Msg: Clone,
1082{
1083 fn clone(&self) -> Self {
1084 Self {
1085 creation: self.creation,
1086 message: self.message.clone(),
1087 occurrence: PhantomData,
1088 }
1089 }
1090}
1091
1092impl<P, Occurrence> ActionItem for ChildDelivery<P, Occurrence>
1093where
1094 P: Protocol,
1095 P::Msg: Send,
1096{
1097 type Custody = (Option<Self>, Option<Self::Reply>);
1098 type Input<'a>
1099 = &'a mut Option<Self>
1100 where
1101 Self: 'a;
1102 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1103
1104 fn prepare_interpretation(
1105 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1106 ) {
1107 prepare_item::<Self>(progress);
1108 }
1109 fn interpretation_input<'a>(
1110 custody: &'a mut Self::Custody,
1111 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1112 where
1113 Self: 'a,
1114 {
1115 let (input, received) = custody;
1116 if input.is_some() && received.is_none() {
1117 Some((input, received))
1118 } else {
1119 None
1120 }
1121 }
1122 fn finish_interpretation(
1123 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1124 ) {
1125 finish_item::<Self>(progress);
1126 }
1127
1128 type Accepted = ();
1129 type Rejection = ChildDeliveryReason;
1130 type Prerequisite = CreationCorrelation<P, Occurrence>;
1131}
1132
1133impl<Child, Source, Input, Occurrence> ActionItem for ChildInput<Child, Source, Input, Occurrence>
1134where
1135 Child: Behavior,
1136 Input: Send,
1137{
1138 type Custody = (Option<Self>, Option<Self::Reply>);
1139 type Input<'a>
1140 = &'a mut Option<Self>
1141 where
1142 Self: 'a;
1143 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1144
1145 fn prepare_interpretation(
1146 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1147 ) {
1148 prepare_item::<Self>(progress);
1149 }
1150 fn interpretation_input<'a>(
1151 custody: &'a mut Self::Custody,
1152 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1153 where
1154 Self: 'a,
1155 {
1156 let (input, received) = custody;
1157 if input.is_some() && received.is_none() {
1158 Some((input, received))
1159 } else {
1160 None
1161 }
1162 }
1163 fn finish_interpretation(
1164 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1165 ) {
1166 finish_item::<Self>(progress);
1167 }
1168
1169 type Accepted = ();
1170 type Rejection = ChildInputReason;
1171 type Prerequisite = CreationCorrelation<Child::Protocol, Occurrence>;
1172}
1173
1174pub trait EstablishChild<Occurrence, C>
1240where
1241 C: Behavior,
1242 BehaviorAddr<C>: EndpointAddress,
1243{
1244 fn establish_child(
1246 &mut self,
1247 creation: RoutedCreation<BehaviorAddr<C>, C>,
1248 ) -> impl Future<
1249 Output = ItemSettlement<
1250 RoutedCreation<BehaviorAddr<C>, C>,
1251 ChildCreationOutcome<C, Occurrence>,
1252 CreationRejection,
1253 Never,
1254 >,
1255 > + Send;
1256}
1257
1258#[doc(hidden)]
1263pub trait ChildCreationProduct<A: Address, Occurrence>: Sized {
1264 type Result;
1265}
1266
1267pub trait DispatchBirth<A: Address, Host>: ChildCreationProduct<A, ChildHead> + Sized {
1276 fn dispatch_birth(
1279 self,
1280 id: CreationId,
1281 route: A::Nonce,
1282 kind: CreationKind,
1283 host: &mut Host,
1284 ) -> impl Future<
1285 Output = ItemSettlement<
1286 RoutedCreation<A, Self>,
1287 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1288 CreationRejection,
1289 Never,
1290 >,
1291 > + Send;
1292}
1293
1294trait CreateSelectedChild<A: Address, Occurrence, Host>:
1295 ChildCreationProduct<A, Occurrence> + Sized
1296{
1297 fn dispatch_birth_at(
1298 self,
1299 id: CreationId,
1300 route: A::Nonce,
1301 kind: CreationKind,
1302 host: &mut Host,
1303 ) -> impl Future<
1304 Output = ItemSettlement<
1305 RoutedCreation<A, Self>,
1306 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1307 CreationRejection,
1308 Never,
1309 >,
1310 > + Send;
1311}
1312
1313impl<A, Child, Host> DispatchBirth<A, Host> for Child
1314where
1315 A: Address,
1316 Child: CreateSelectedChild<A, ChildHead, Host>,
1317{
1318 fn dispatch_birth(
1319 self,
1320 id: CreationId,
1321 route: A::Nonce,
1322 kind: CreationKind,
1323 host: &mut Host,
1324 ) -> impl Future<
1325 Output = ItemSettlement<
1326 RoutedCreation<A, Self>,
1327 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1328 CreationRejection,
1329 Never,
1330 >,
1331 > + Send {
1332 self.dispatch_birth_at(id, route, kind, host)
1333 }
1334}
1335
1336#[derive(Debug, Clone, PartialEq, Eq)]
1420pub enum ChildChoice<Head, Tail> {
1421 Head(Head),
1423 Tail(Tail),
1425}
1426
1427#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1429pub struct ChildHead;
1430
1431#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1433pub struct ChildTail<Position>(PhantomData<fn() -> Position>);
1434
1435pub trait ChildPosition<Children, Child: Behavior>: sealed::ChildPosition {}
1488
1489impl sealed::ChildPosition for ChildHead {}
1490
1491impl<Child: Behavior> ChildPosition<Child, Child> for ChildHead {}
1492
1493impl<Head: Behavior, Tail> ChildPosition<ChildChoice<Head, Tail>, Head> for ChildHead {}
1494
1495impl<Position> sealed::ChildPosition for ChildTail<Position> {}
1496
1497impl<Head, Tail, Position, Child> ChildPosition<ChildChoice<Head, Tail>, Child>
1498 for ChildTail<Position>
1499where
1500 Child: Behavior,
1501 Position: ChildPosition<Tail, Child>,
1502{
1503}
1504
1505pub trait BirthNodeAppend<Tail>: sealed::BirthNode + Sized
1527where
1528 Tail: sealed::BirthNode,
1529{
1530 type Output: sealed::BirthNode;
1533
1534 fn append_prefix(self) -> Self::Output;
1537
1538 fn append_tail(tail: Tail) -> Self::Output;
1540
1541 #[must_use]
1543 fn append_creations<A: Address>(
1544 prefix: Creations<CreateChild<A, Self>>,
1545 tail: Creations<CreateChild<A, Tail>>,
1546 ) -> Creations<CreateChild<A, Self::Output>> {
1547 let mut combined = Vec::with_capacity(prefix.len() + tail.len());
1548 combined.extend(prefix.into_iter().map(|creation| {
1549 let (id, child, kind) = creation.into_parts();
1550 CreateChild::from_parts(id, Self::append_prefix(child), kind)
1551 }));
1552 combined.extend(tail.into_iter().map(|creation| {
1553 let (id, child, kind) = creation.into_parts();
1554 CreateChild::from_parts(id, Self::append_tail(child), kind)
1555 }));
1556 Creations::from_items(combined)
1557 }
1558}
1559
1560impl<Tail> BirthNodeAppend<Tail> for Never
1561where
1562 Tail: sealed::BirthNode,
1563{
1564 type Output = Tail;
1565
1566 fn append_prefix(self) -> Self::Output {
1567 match self {}
1568 }
1569
1570 fn append_tail(tail: Tail) -> Self::Output {
1571 tail
1572 }
1573}
1574
1575impl<Node> BirthNodeAppend<Never> for Node
1576where
1577 Node: sealed::NonEmptyBirthNode,
1578{
1579 type Output = Node;
1580
1581 fn append_prefix(self) -> Self::Output {
1582 self
1583 }
1584
1585 fn append_tail(tail: Never) -> Self::Output {
1586 match tail {}
1587 }
1588}
1589
1590impl<Child, Tail> BirthNodeAppend<Tail> for Child
1591where
1592 Child: Behavior,
1593 Tail: sealed::NonEmptyBirthNode,
1594{
1595 type Output = ChildChoice<Child, Tail>;
1596
1597 fn append_prefix(self) -> Self::Output {
1598 ChildChoice::Head(self)
1599 }
1600
1601 fn append_tail(tail: Tail) -> Self::Output {
1602 ChildChoice::Tail(tail)
1603 }
1604}
1605
1606impl<Head, Rest, Tail> BirthNodeAppend<Tail> for ChildChoice<Head, Rest>
1607where
1608 Head: Behavior,
1609 Rest: sealed::BirthNode + BirthNodeAppend<Tail>,
1610 Tail: sealed::NonEmptyBirthNode,
1611 Rest::Output: sealed::BirthNode,
1612{
1613 type Output = ChildChoice<Head, Rest::Output>;
1614
1615 fn append_prefix(self) -> Self::Output {
1616 match self {
1617 ChildChoice::Head(head) => ChildChoice::Head(head),
1618 ChildChoice::Tail(rest) => ChildChoice::Tail(rest.append_prefix()),
1619 }
1620 }
1621
1622 fn append_tail(tail: Tail) -> Self::Output {
1623 ChildChoice::Tail(Rest::append_tail(tail))
1624 }
1625}
1626
1627impl<Parent: Behavior> ChildOccurrence<Parent> for ChildHead {
1628 type Resolution = StructuralChildOccurrence<Self>;
1629}
1630
1631impl<Parent: Behavior, Position> ChildOccurrence<Parent> for ChildTail<Position> {
1632 type Resolution = StructuralChildOccurrence<Self>;
1633}
1634
1635#[doc(hidden)]
1642pub trait ChildOccurrenceResolution<Parent: Behavior, Occurrence>:
1643 sealed::ChildOccurrenceDescriptor + sealed::OccurrenceResolution<Parent, Occurrence>
1644{
1645}
1646
1647impl<Parent, Occurrence> ChildOccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1648where
1649 Parent: Behavior,
1650 Occurrence: ChildRole<Parent>,
1651{
1652}
1653
1654impl<Parent: Behavior> ChildOccurrenceResolution<Parent, ChildHead>
1655 for StructuralChildOccurrence<ChildHead>
1656{
1657}
1658
1659impl<Parent: Behavior, Position> ChildOccurrenceResolution<Parent, ChildTail<Position>>
1660 for StructuralChildOccurrence<ChildTail<Position>>
1661{
1662}
1663
1664#[doc(hidden)]
1666pub trait ResolveChildOccurrenceDescriptor<Emitter: Behavior, Occurrence>:
1667 sealed::ChildOccurrenceDescriptor + sealed::ResolveDescriptor<Emitter, Occurrence>
1668{
1669 type Child: Behavior;
1670 type Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Self::Child>;
1671}
1672
1673impl<Emitter, Occurrence, Position> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1674 for StructuralChildOccurrence<Position>
1675where
1676 Emitter: Behavior,
1677 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1678 Position: ChildPosition<
1679 <Emitter::Birth as BirthMode>::Child,
1680 <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child,
1681 >,
1682{
1683 type Child = <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child;
1684 type Position = Position;
1685}
1686
1687impl<Emitter, Occurrence> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1688 for DeclaredChildOccurrence
1689where
1690 Emitter:
1691 Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol> + BehaviorBase,
1692 Emitter::Base: Behavior,
1693 Occurrence: ChildRole<Emitter::Base>,
1694 <Emitter::Birth as BirthMode>::Child:
1695 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1696 Occurrence::Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1697{
1698 type Child = Occurrence::Child;
1699 type Position = Occurrence::Position;
1700}
1701
1702#[doc(hidden)]
1704pub trait BirthNodeAt<Position>: sealed::BirthNode {
1705 type Child: Behavior;
1706}
1707
1708impl<Child: Behavior> BirthNodeAt<ChildHead> for Child {
1709 type Child = Child;
1710}
1711
1712impl<Head: Behavior, Tail> BirthNodeAt<ChildHead> for ChildChoice<Head, Tail>
1713where
1714 Tail: sealed::BirthNode,
1715{
1716 type Child = Head;
1717}
1718
1719impl<Head, Tail, Position> BirthNodeAt<ChildTail<Position>> for ChildChoice<Head, Tail>
1720where
1721 Head: Behavior,
1722 Tail: BirthNodeAt<Position>,
1723{
1724 type Child = <Tail as BirthNodeAt<Position>>::Child;
1725}
1726
1727pub trait ChildOccurrenceShape {
1757 type Empty;
1759}
1760
1761pub trait ChildOccurrenceMember<Occurrence, Child: Behavior, Tail>: ChildOccurrenceShape {
1841 type Member;
1843}
1844
1845pub trait ChildOccurrenceProduct<Shape>: sealed::BirthNode
1876where
1877 Shape: ChildOccurrenceShape,
1878{
1879 type Product;
1881}
1882
1883#[doc(hidden)]
1886pub trait ChildOccurrenceProductAt<Occurrence, Shape>: sealed::BirthNode
1887where
1888 Shape: ChildOccurrenceShape,
1889{
1890 type Product;
1891}
1892
1893impl<Node, Shape> ChildOccurrenceProduct<Shape> for Node
1894where
1895 Node: ChildOccurrenceProductAt<ChildHead, Shape>,
1896 Shape: ChildOccurrenceShape,
1897{
1898 type Product = <Node as ChildOccurrenceProductAt<ChildHead, Shape>>::Product;
1899}
1900
1901impl<Occurrence, Shape, Child> ChildOccurrenceProductAt<Occurrence, Shape> for Child
1902where
1903 Shape: ChildOccurrenceShape
1904 + ChildOccurrenceMember<Occurrence, Child, <Shape as ChildOccurrenceShape>::Empty>,
1905 Child: Behavior,
1906{
1907 type Product = <Shape as ChildOccurrenceMember<
1908 Occurrence,
1909 Child,
1910 <Shape as ChildOccurrenceShape>::Empty,
1911 >>::Member;
1912}
1913
1914impl<Occurrence, Shape, Head, Tail> ChildOccurrenceProductAt<Occurrence, Shape>
1915 for ChildChoice<Head, Tail>
1916where
1917 Shape: ChildOccurrenceShape
1918 + ChildOccurrenceMember<
1919 Occurrence,
1920 Head,
1921 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1922 >,
1923 Head: Behavior,
1924 Tail: ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>,
1925{
1926 type Product = <Shape as ChildOccurrenceMember<
1927 Occurrence,
1928 Head,
1929 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1930 >>::Member;
1931}
1932
1933impl<Occurrence, Shape> ChildOccurrenceProductAt<Occurrence, Shape> for Never
1934where
1935 Shape: ChildOccurrenceShape,
1936{
1937 type Product = Shape::Empty;
1938}
1939
1940pub type ChildOccurrences<Node, Shape> = <Node as ChildOccurrenceProduct<Shape>>::Product;
1942
1943mod sealed {
1944 use super::{
1945 Behavior, BehaviorBase, BirthMode, BirthNodeAt, ChildChoice, ChildHead, ChildOccurrence,
1946 ChildRole, ChildTail, DeclaredChildOccurrence, Never, ResolveChildOccurrenceDescriptor,
1947 StructuralChildOccurrence,
1948 };
1949
1950 pub trait BirthNode {}
1951
1952 pub trait NonEmptyBirthNode: BirthNode {}
1953
1954 impl<Child: Behavior> BirthNode for Child {}
1955 impl<Child: Behavior> NonEmptyBirthNode for Child {}
1956
1957 impl<Head, Tail> BirthNode for ChildChoice<Head, Tail>
1958 where
1959 Head: Behavior,
1960 Tail: BirthNode,
1961 {
1962 }
1963
1964 impl<Head, Tail> NonEmptyBirthNode for ChildChoice<Head, Tail>
1965 where
1966 Head: Behavior,
1967 Tail: BirthNode,
1968 {
1969 }
1970
1971 impl BirthNode for Never {}
1972
1973 pub trait ChildPosition {}
1974 pub trait ChildProduct {}
1975
1976 pub trait ChildOccurrenceDescriptor {}
1977
1978 impl ChildOccurrenceDescriptor for DeclaredChildOccurrence {}
1979
1980 impl<Position> ChildOccurrenceDescriptor for StructuralChildOccurrence<Position> {}
1981
1982 pub trait OccurrenceResolution<Parent: Behavior, Occurrence> {}
1983
1984 impl<Parent, Occurrence> OccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1985 where
1986 Parent: Behavior,
1987 Occurrence: ChildRole<Parent>,
1988 {
1989 }
1990
1991 impl<Parent: Behavior> OccurrenceResolution<Parent, ChildHead>
1992 for StructuralChildOccurrence<ChildHead>
1993 {
1994 }
1995
1996 impl<Parent: Behavior, Position> OccurrenceResolution<Parent, ChildTail<Position>>
1997 for StructuralChildOccurrence<ChildTail<Position>>
1998 {
1999 }
2000
2001 pub trait ResolveDescriptor<Emitter: Behavior, Occurrence> {}
2002
2003 impl<Emitter, Occurrence, Position> ResolveDescriptor<Emitter, Occurrence>
2004 for StructuralChildOccurrence<Position>
2005 where
2006 Emitter: Behavior,
2007 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
2008 {
2009 }
2010
2011 impl<Emitter, Occurrence> ResolveDescriptor<Emitter, Occurrence> for DeclaredChildOccurrence
2012 where
2013 Emitter: Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol>
2014 + BehaviorBase,
2015 Emitter::Base: Behavior,
2016 Occurrence: ChildRole<Emitter::Base>,
2017 <Emitter::Birth as BirthMode>::Child:
2018 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
2019 Occurrence::Position:
2020 super::ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
2021 {
2022 }
2023
2024 pub trait ResolveChildOccurrence<Occurrence> {}
2025
2026 impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
2027 where
2028 Emitter: Behavior + BehaviorBase,
2029 Emitter::Base: Behavior,
2030 Occurrence: ChildOccurrence<Emitter::Base>,
2031 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
2032 {
2033 }
2034}
2035
2036#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2038pub struct NoChildren;
2039
2040impl sealed::ChildProduct for NoChildren {}
2041
2042pub struct ChildCons<A: Address, C, Earlier> {
2044 creation: CreateChild<A, C>,
2045 earlier: Earlier,
2046}
2047
2048impl<A: Address, C, Earlier> sealed::ChildProduct for ChildCons<A, C, Earlier> {}
2049
2050pub struct Children<A: Address, Product = NoChildren> {
2056 product: Product,
2057 address: PhantomData<fn() -> A>,
2058}
2059
2060pub trait ChildProduct<A: Address>: sealed::ChildProduct + Sized {
2062 type Choice: BirthNodeAppend<Never>;
2064
2065 #[doc(hidden)]
2066 fn stage(self) -> Vec<CreateChild<A, Self::Choice>>;
2067}
2068
2069impl<A: Address> ChildProduct<A> for NoChildren {
2070 type Choice = Never;
2071
2072 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
2073 Vec::new()
2074 }
2075}
2076
2077impl<A, C, Earlier> ChildProduct<A> for ChildCons<A, C, Earlier>
2078where
2079 A: Address,
2080 C: Behavior,
2081 C::Protocol: Protocol<Addr = A>,
2082 Earlier: ChildProduct<A>,
2083{
2084 type Choice = ChildChoice<C, Earlier::Choice>;
2085
2086 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
2087 let earlier = self.earlier.stage();
2088 let mut creates = earlier
2089 .into_iter()
2090 .map(|creation| {
2091 let (id, child, kind) = creation.into_parts();
2092 CreateChild::from_parts(id, ChildChoice::Tail(child), kind)
2093 })
2094 .collect::<Vec<_>>();
2095 let (id, child, kind) = self.creation.into_parts();
2096 creates.push(CreateChild::from_parts(id, ChildChoice::Head(child), kind));
2097 creates
2098 }
2099}
2100
2101impl<A: Address> Children<A, NoChildren> {
2102 #[must_use]
2104 pub const fn new() -> Self {
2105 Self {
2106 product: NoChildren,
2107 address: PhantomData,
2108 }
2109 }
2110}
2111
2112impl<A: Address> Default for Children<A, NoChildren> {
2113 fn default() -> Self {
2114 Self::new()
2115 }
2116}
2117
2118impl<A: Address, Product> Children<A, Product> {
2119 #[must_use]
2121 pub fn create<C>(self, creation: CreateChild<A, C>) -> Children<A, ChildCons<A, C, Product>>
2122 where
2123 C: Behavior,
2124 C::Protocol: Protocol<Addr = A>,
2125 {
2126 Children {
2127 product: ChildCons {
2128 creation,
2129 earlier: self.product,
2130 },
2131 address: PhantomData,
2132 }
2133 }
2134
2135 #[must_use]
2137 pub fn child<C>(self, id: CreationId, child: C) -> Children<A, ChildCons<A, C, Product>>
2138 where
2139 C: Behavior,
2140 C::Protocol: Protocol<Addr = A>,
2141 {
2142 self.create(CreateChild::birth(id, child))
2143 }
2144}
2145
2146impl<A, Product> Children<A, Product>
2147where
2148 A: Address,
2149 Product: ChildProduct<A>,
2150{
2151 #[must_use]
2153 pub fn into_creates(self) -> Creations<CreateChild<A, Product::Choice>> {
2154 Creations::from_items(self.product.stage())
2155 }
2156}
2157
2158impl<A, Occurrence, Head, Tail> ChildCreationProduct<A, Occurrence> for ChildChoice<Head, Tail>
2159where
2160 A: EndpointAddress,
2161 Head: Behavior,
2162 Head::Protocol: Protocol<Addr = A>,
2163 Tail: ChildCreationProduct<A, ChildTail<Occurrence>>,
2164{
2165 type Result = ChildChoice<
2166 ChildCreationOutcome<Head, Occurrence>,
2167 <Tail as ChildCreationProduct<A, ChildTail<Occurrence>>>::Result,
2168 >;
2169}
2170
2171impl<A, Occurrence, Head, Tail, Host> CreateSelectedChild<A, Occurrence, Host>
2172 for ChildChoice<Head, Tail>
2173where
2174 A: EndpointAddress,
2175 A::Nonce: Send,
2176 Head: Behavior + Send,
2177 Head::Protocol: Protocol<Addr = A>,
2178 Tail: CreateSelectedChild<A, ChildTail<Occurrence>, Host> + Send,
2179 Host: EstablishChild<Occurrence, Head> + Send,
2180{
2181 async fn dispatch_birth_at(
2182 self,
2183 id: CreationId,
2184 route: A::Nonce,
2185 kind: CreationKind,
2186 host: &mut Host,
2187 ) -> ItemSettlement<
2188 RoutedCreation<A, Self>,
2189 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2190 CreationRejection,
2191 Never,
2192 > {
2193 match self {
2194 Self::Head(child) => {
2195 let creation = RoutedCreation::new(CreateChild::from_parts(id, child, kind), route);
2196 match host.establish_child(creation).await {
2197 ItemSettlement::Accepted(receipt) => {
2198 ItemSettlement::Accepted(ChildChoice::Head(receipt))
2199 }
2200 ItemSettlement::Rejected { item, reason } => {
2201 let (creation, route) = item.into_parts();
2202 let (id, child, kind) = creation.into_parts();
2203 ItemSettlement::Rejected {
2204 item: RoutedCreation::new(
2205 CreateChild::from_parts(id, Self::Head(child), kind),
2206 route,
2207 ),
2208 reason,
2209 }
2210 }
2211 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2212 ItemSettlement::Corrupt { item, fault } => {
2213 let (creation, route) = item.into_parts();
2214 let (id, child, kind) = creation.into_parts();
2215 ItemSettlement::Corrupt {
2216 item: RoutedCreation::new(
2217 CreateChild::from_parts(id, Self::Head(child), kind),
2218 route,
2219 ),
2220 fault,
2221 }
2222 }
2223 }
2224 }
2225 Self::Tail(tail) => match tail.dispatch_birth_at(id, route, kind, host).await {
2226 ItemSettlement::Accepted(receipt) => {
2227 ItemSettlement::Accepted(ChildChoice::Tail(receipt))
2228 }
2229 ItemSettlement::Rejected { item, reason } => {
2230 let (creation, route) = item.into_parts();
2231 let (id, child, kind) = creation.into_parts();
2232 ItemSettlement::Rejected {
2233 item: RoutedCreation::new(
2234 CreateChild::from_parts(id, Self::Tail(child), kind),
2235 route,
2236 ),
2237 reason,
2238 }
2239 }
2240 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2241 ItemSettlement::Corrupt { item, fault } => {
2242 let (creation, route) = item.into_parts();
2243 let (id, child, kind) = creation.into_parts();
2244 ItemSettlement::Corrupt {
2245 item: RoutedCreation::new(
2246 CreateChild::from_parts(id, Self::Tail(child), kind),
2247 route,
2248 ),
2249 fault,
2250 }
2251 }
2252 },
2253 }
2254 }
2255}
2256
2257impl<A, Occurrence> ChildCreationProduct<A, Occurrence> for Never
2258where
2259 A: Address,
2260{
2261 type Result = Never;
2262}
2263
2264impl<A, Occurrence, Host> CreateSelectedChild<A, Occurrence, Host> for Never
2265where
2266 A: Address,
2267{
2268 fn dispatch_birth_at(
2269 self,
2270 _id: CreationId,
2271 _route: A::Nonce,
2272 _kind: CreationKind,
2273 _host: &mut Host,
2274 ) -> impl Future<
2275 Output = ItemSettlement<
2276 RoutedCreation<A, Self>,
2277 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2278 CreationRejection,
2279 Never,
2280 >,
2281 > + Send {
2282 async move { match self {} }
2283 }
2284}
2285
2286impl<A, Occurrence, C> ChildCreationProduct<A, Occurrence> for C
2287where
2288 A: EndpointAddress,
2289 C: Behavior,
2290 C::Protocol: Protocol<Addr = A>,
2291{
2292 type Result = ChildCreationOutcome<C, Occurrence>;
2293}
2294
2295impl<A, Occurrence, C, Host> CreateSelectedChild<A, Occurrence, Host> for C
2296where
2297 A: EndpointAddress,
2298 C: Behavior,
2299 C::Protocol: Protocol<Addr = A>,
2300 Host: EstablishChild<Occurrence, C>,
2301{
2302 fn dispatch_birth_at(
2303 self,
2304 id: CreationId,
2305 route: A::Nonce,
2306 kind: CreationKind,
2307 host: &mut Host,
2308 ) -> impl Future<
2309 Output = ItemSettlement<
2310 RoutedCreation<A, Self>,
2311 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2312 CreationRejection,
2313 Never,
2314 >,
2315 > + Send {
2316 host.establish_child(RoutedCreation::new(
2317 CreateChild::from_parts(id, self, kind),
2318 route,
2319 ))
2320 }
2321}
2322
2323pub trait BirthMode {
2325 type Child;
2326}
2327
2328pub struct NoBirthProtocols;
2330
2331pub struct BirthProtocol<P: Protocol, Tail> {
2333 protocol: PhantomData<fn() -> P>,
2334 tail: PhantomData<fn() -> Tail>,
2335}
2336
2337pub struct BirthProtocolHead;
2339
2340pub struct BirthProtocolTail<Position>(PhantomData<fn() -> Position>);
2342
2343pub trait BirthProtocolAt<P: Protocol, Position> {}
2345
2346impl<P: Protocol, Tail> BirthProtocolAt<P, BirthProtocolHead> for BirthProtocol<P, Tail> {}
2347
2348impl<Head, Tail, P, Position> BirthProtocolAt<P, BirthProtocolTail<Position>>
2349 for BirthProtocol<Head, Tail>
2350where
2351 Head: Protocol,
2352 P: Protocol,
2353 Tail: BirthProtocolAt<P, Position>,
2354{
2355}
2356
2357pub trait BirthProtocolProduct {
2359 type Append<Tail: BirthProtocolProduct>: BirthProtocolProduct;
2360}
2361
2362impl BirthProtocolProduct for NoBirthProtocols {
2363 type Append<Tail: BirthProtocolProduct> = Tail;
2364}
2365
2366impl<P, Rest> BirthProtocolProduct for BirthProtocol<P, Rest>
2367where
2368 P: Protocol,
2369 Rest: BirthProtocolProduct,
2370{
2371 type Append<Tail: BirthProtocolProduct> = BirthProtocol<P, Rest::Append<Tail>>;
2372}
2373
2374pub trait BirthProtocols: Behavior {
2380 type Protocols: BirthProtocolProduct;
2381}
2382
2383impl<B> BirthProtocols for B
2384where
2385 B: Behavior,
2386 B::Birth: BirthModeProtocols,
2387{
2388 type Protocols = BirthProtocol<B::Protocol, <B::Birth as BirthModeProtocols>::Protocols>;
2389}
2390
2391#[doc(hidden)]
2392pub trait BirthModeProtocols {
2393 type Protocols: BirthProtocolProduct;
2394}
2395
2396impl<M> BirthModeProtocols for M
2397where
2398 M: BirthMode,
2399 M::Child: BirthNodeProtocols,
2400{
2401 type Protocols = <M::Child as BirthNodeProtocols>::Protocols;
2402}
2403
2404#[doc(hidden)]
2405pub trait BirthNodeProtocols {
2406 type Protocols: BirthProtocolProduct;
2407}
2408
2409impl<B> BirthNodeProtocols for B
2410where
2411 B: BirthProtocols,
2412{
2413 type Protocols = B::Protocols;
2414}
2415
2416impl<Head, Tail> BirthNodeProtocols for ChildChoice<Head, Tail>
2417where
2418 Head: BirthNodeProtocols,
2419 Tail: BirthNodeProtocols,
2420{
2421 type Protocols = <Head::Protocols as BirthProtocolProduct>::Append<Tail::Protocols>;
2422}
2423
2424impl BirthNodeProtocols for Never {
2425 type Protocols = NoBirthProtocols;
2426}
2427
2428#[doc(hidden)]
2433pub trait BirthNodeLogicalHosts {
2434 type LogicalHosts: BirthProtocolProduct;
2435}
2436
2437impl<B> BirthNodeLogicalHosts for B
2438where
2439 B: crate::LogicalHostRequirements,
2440{
2441 type LogicalHosts = B::LogicalHosts;
2442}
2443
2444impl<Head, Tail> BirthNodeLogicalHosts for ChildChoice<Head, Tail>
2445where
2446 Head: BirthNodeLogicalHosts,
2447 Tail: BirthNodeLogicalHosts,
2448{
2449 type LogicalHosts = <Head::LogicalHosts as BirthProtocolProduct>::Append<Tail::LogicalHosts>;
2450}
2451
2452impl BirthNodeLogicalHosts for Never {
2453 type LogicalHosts = NoBirthProtocols;
2454}
2455
2456#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2458pub struct NoBirths;
2459
2460impl BirthMode for NoBirths {
2461 type Child = Never;
2462}
2463
2464#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2466pub struct Births<C>(PhantomData<fn() -> C>);
2467
2468impl<C> BirthMode for Births<C> {
2469 type Child = C;
2470}
2471
2472#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2480pub struct RetirementBirths<C>(PhantomData<fn() -> C>);
2481
2482impl<C> BirthMode for RetirementBirths<C> {
2483 type Child = C;
2484}
2485
2486#[cfg(test)]
2487mod tests {
2488 use super::*;
2489 use crate::{
2490 Actions, BehaviorActed, ChildInputIngress, EventLayer, Interpretation, NoBirths, User,
2491 };
2492
2493 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2494 struct TestAddr(u64);
2495
2496 impl Address for TestAddr {
2497 type Nonce = u64;
2498 }
2499
2500 struct TestEndpoint<P>(PhantomData<fn() -> P>);
2501
2502 impl<P> Clone for TestEndpoint<P> {
2503 fn clone(&self) -> Self {
2504 *self
2505 }
2506 }
2507
2508 impl<P> Copy for TestEndpoint<P> {}
2509
2510 struct TestInstalled<B: Behavior> {
2511 endpoint: TestEndpoint<B::Protocol>,
2512 control: std::sync::mpsc::Sender<B::Event>,
2513 }
2514
2515 impl<B: Behavior> Clone for TestInstalled<B> {
2516 fn clone(&self) -> Self {
2517 Self {
2518 endpoint: self.endpoint,
2519 control: self.control.clone(),
2520 }
2521 }
2522 }
2523
2524 impl EndpointAddress for TestAddr {
2525 type Established<P>
2526 = TestEndpoint<P>
2527 where
2528 P: Protocol<Addr = Self>;
2529
2530 type Installed<B>
2531 = TestInstalled<B>
2532 where
2533 B: Behavior<Protocol: Protocol<Addr = Self>>;
2534
2535 fn recipient<B>(installed: &Self::Installed<B>) -> Self::Established<B::Protocol>
2536 where
2537 B: Behavior<Protocol: Protocol<Addr = Self>>,
2538 {
2539 installed.endpoint
2540 }
2541 }
2542
2543 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2544 struct Child;
2545
2546 struct SharedProtocol;
2547
2548 impl behavior::Protocol for SharedProtocol {
2549 type Addr = TestAddr;
2550 type Msg = u8;
2551 }
2552
2553 struct Primary;
2554 struct Fallback;
2555
2556 macro_rules! shared_protocol_behavior {
2557 ($behavior:ty, $birth:ty) => {
2558 impl Behavior for $behavior {
2559 type Protocol = SharedProtocol;
2560 type Event = User<TestAddr, u8>;
2561 type Sends = Vec<Never>;
2562 type Ph = Never;
2563 type Error = Never;
2564 type Birth = $birth;
2565
2566 fn transition(
2567 &mut self,
2568 _: crate::ActiveTurn,
2569 _: Self::Event,
2570 ) -> BehaviorActed<Self> {
2571 Ok(Actions::cont())
2572 }
2573 }
2574 };
2575 }
2576
2577 shared_protocol_behavior!(Primary, Births<Child>);
2578 shared_protocol_behavior!(Fallback, NoBirths);
2579
2580 impl behavior::Protocol for Child {
2581 type Addr = TestAddr;
2582 type Msg = u8;
2583 }
2584
2585 impl Behavior for Child {
2586 type Protocol = Self;
2587 type Event = User<TestAddr, u8>;
2588 type Sends = Vec<Never>;
2589 type Ph = Never;
2590 type Error = Never;
2591 type Birth = NoBirths;
2592
2593 fn transition(&mut self, _: crate::ActiveTurn, _: Self::Event) -> BehaviorActed<Self> {
2594 Ok(Actions::cont())
2595 }
2596 }
2597
2598 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2599 enum ChildPlan {
2600 CreateChild,
2601 RejectBeforeTransfer,
2602 }
2603
2604 struct RecordingHost {
2605 calls: usize,
2606 observed: Vec<(CreationId, u64, CreationKind)>,
2607 plan: ChildPlan,
2608 control_receivers: Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2609 }
2610
2611 #[derive(Debug, PartialEq, Eq)]
2612 enum SharedCreation {
2613 Primary(CreationId, u64),
2614 Fallback(CreationId, u64),
2615 }
2616
2617 #[derive(Default)]
2618 struct SharedProtocolHost(
2619 Vec<SharedCreation>,
2620 Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2621 );
2622
2623 impl EstablishChild<ChildHead, Primary> for SharedProtocolHost {
2624 async fn establish_child(
2625 &mut self,
2626 creation: RoutedCreation<TestAddr, Primary>,
2627 ) -> ItemSettlement<
2628 RoutedCreation<TestAddr, Primary>,
2629 ChildCreationOutcome<Primary, ChildHead>,
2630 CreationRejection,
2631 Never,
2632 > {
2633 let id = creation.id();
2634 let kind = creation.kind();
2635 let route = creation.route();
2636 let (creation, _) = creation.into_parts();
2637 let (_, _child, _) = creation.into_parts();
2638 self.0.push(SharedCreation::Primary(id, route));
2639 let (control, receiver) = std::sync::mpsc::channel();
2640 self.1.push(receiver);
2641 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2642 id,
2643 kind,
2644 EstablishedActor::issued(TestInstalled {
2645 endpoint: TestEndpoint(PhantomData),
2646 control,
2647 }),
2648 )))
2649 }
2650 }
2651
2652 impl EstablishChild<ChildTail<ChildHead>, Fallback> for SharedProtocolHost {
2653 async fn establish_child(
2654 &mut self,
2655 creation: RoutedCreation<TestAddr, Fallback>,
2656 ) -> ItemSettlement<
2657 RoutedCreation<TestAddr, Fallback>,
2658 ChildCreationOutcome<Fallback, ChildTail<ChildHead>>,
2659 CreationRejection,
2660 Never,
2661 > {
2662 let id = creation.id();
2663 let kind = creation.kind();
2664 let route = creation.route();
2665 let (creation, _) = creation.into_parts();
2666 let (_, _child, _) = creation.into_parts();
2667 self.0.push(SharedCreation::Fallback(id, route));
2668 let (control, receiver) = std::sync::mpsc::channel();
2669 self.1.push(receiver);
2670 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2671 id,
2672 kind,
2673 EstablishedActor::issued(TestInstalled {
2674 endpoint: TestEndpoint(PhantomData),
2675 control,
2676 }),
2677 )))
2678 }
2679 }
2680
2681 impl EstablishChild<ChildHead, Child> for RecordingHost {
2682 async fn establish_child(
2683 &mut self,
2684 creation: RoutedCreation<TestAddr, Child>,
2685 ) -> ItemSettlement<
2686 RoutedCreation<TestAddr, Child>,
2687 ChildCreationOutcome<Child, ChildHead>,
2688 CreationRejection,
2689 Never,
2690 > {
2691 self.calls += 1;
2692 self.observed
2693 .push((creation.id(), creation.route(), creation.kind()));
2694 match self.plan {
2695 ChildPlan::CreateChild => {
2696 let id = creation.id();
2697 let kind = creation.kind();
2698 let (creation, _) = creation.into_parts();
2699 let (_, _child, _) = creation.into_parts();
2700 let (control, receiver) = std::sync::mpsc::channel();
2701 self.control_receivers.push(receiver);
2702 ItemSettlement::Accepted(ChildCreationOutcome::Established(
2703 CommittedChild::new(
2704 id,
2705 kind,
2706 EstablishedActor::issued(TestInstalled {
2707 endpoint: TestEndpoint(PhantomData),
2708 control,
2709 }),
2710 ),
2711 ))
2712 }
2713 ChildPlan::RejectBeforeTransfer => ItemSettlement::Rejected {
2714 item: creation,
2715 reason: CreationRejection::EnvironmentFailed,
2716 },
2717 }
2718 }
2719 }
2720
2721 fn host(plan: ChildPlan) -> RecordingHost {
2722 RecordingHost {
2723 calls: 0,
2724 observed: Vec::new(),
2725 plan,
2726 control_receivers: Vec::new(),
2727 }
2728 }
2729
2730 fn assert_send<T: Send>(_: &T) {}
2731
2732 #[test]
2733 fn empty_child_product_stages_no_creations() {
2734 let creations = <NoChildren as ChildProduct<TestAddr>>::stage(NoChildren);
2735 assert!(creations.is_empty());
2736 }
2737
2738 #[test]
2739 fn creation_values_preserve_ids_order_and_debug_identity() {
2740 let mut sequence = CreationSequence::new();
2741 let first = sequence.issue().expect("the first creation ID exists");
2742 let second = sequence.issue().expect("the second creation ID exists");
2743 assert_eq!(first.get(), 1);
2744 assert_eq!(second.get(), 2);
2745
2746 let first_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2747 let same_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2748 let second_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(second);
2749 assert_eq!(first_correlation, same_correlation);
2750 assert_ne!(first_correlation, second_correlation);
2751 assert_eq!(
2752 format!("{first_correlation:?}"),
2753 "CreationCorrelation(CreationId(1))"
2754 );
2755
2756 let mut creations = Creations::one(1_u8);
2757 creations.extend([2, 3]);
2758 assert_eq!(creations.len(), 3);
2759 assert!(!creations.is_empty());
2760 assert_eq!(creations.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
2761 let borrowed = (&creations).into_iter().copied().collect::<Vec<_>>();
2762 assert_eq!(borrowed, [1, 2, 3]);
2763
2764 let collected: Creations<_> = [4_u8, 5].into_iter().collect();
2765 assert_eq!(collected.len(), 2);
2766 let collected_values = collected.into_iter().collect::<Vec<_>>();
2767 assert_eq!(collected_values, [4, 5]);
2768
2769 let returned = ChildCreationSettled::<Child, ChildHead>::new(SettledItem::Unattempted(
2770 RoutedCreation::new(CreateChild::birth(first, Child), 17),
2771 ));
2772 assert_eq!(format!("{returned:?}"), "ChildCreationSettled { .. }");
2773 }
2774
2775 #[tokio::test]
2776 async fn concrete_child_dispatches_once_with_exact_creation_and_route() {
2777 let mut sequence = CreationSequence::new();
2778 let previous = sequence.issue().expect("the previous ID exists");
2779 let id = sequence.issue().expect("the replacement ID exists");
2780 let mut host = host(ChildPlan::CreateChild);
2781 let kind = CreationKind::replacement(previous);
2782 let future = Child.dispatch_birth(id, 17, kind, &mut host);
2783 assert_send(&future);
2784 let result = future.await;
2785
2786 let ItemSettlement::Accepted(ChildCreationOutcome::Established(established)) = result
2787 else {
2788 panic!("expected the child to be created");
2789 };
2790 assert_eq!(established.id(), id);
2791 assert_eq!(host.calls, 1);
2792 assert_eq!(host.observed, [(id, 17, kind)]);
2793 }
2794
2795 #[tokio::test]
2796 async fn concrete_child_returns_the_exact_rejected_creation_without_retry() {
2797 let mut sequence = CreationSequence::new();
2798 let previous = sequence.issue().expect("the previous ID exists");
2799 let id = sequence.issue().expect("the replacement ID exists");
2800 let mut host = host(ChildPlan::RejectBeforeTransfer);
2801 let kind = CreationKind::replacement(previous);
2802 let future = Child.dispatch_birth(id, 23, kind, &mut host);
2803 assert_send(&future);
2804 let result = future.await;
2805
2806 let ItemSettlement::Rejected { item, reason } = result else {
2807 panic!("expected refusal before child ownership transfer");
2808 };
2809 assert_eq!(
2810 item,
2811 RoutedCreation::new(CreateChild::replacement(id, previous, Child), 23)
2812 );
2813 assert_eq!(reason, CreationRejection::EnvironmentFailed);
2814 assert_eq!(host.calls, 1);
2815 assert_eq!(host.observed, [(id, 23, kind)]);
2816 }
2817
2818 #[tokio::test]
2819 async fn distinct_child_alternatives_preserve_one_canonical_protocol_identity() {
2820 type Alternatives = ChildChoice<Primary, ChildChoice<Fallback, Never>>;
2821
2822 fn requires_shared_protocol<C: Behavior<Protocol = SharedProtocol>>() {}
2823 requires_shared_protocol::<Primary>();
2824 requires_shared_protocol::<Fallback>();
2825
2826 let mut sequence = CreationSequence::new();
2827 let primary_id = sequence.issue().expect("the primary ID exists");
2828 let fallback_id = sequence.issue().expect("the fallback ID exists");
2829 let mut host = SharedProtocolHost::default();
2830 let primary = Alternatives::Head(Primary)
2831 .dispatch_birth(primary_id, 11, CreationKind::Birth, &mut host)
2832 .await;
2833 let fallback = Alternatives::Tail(ChildChoice::Head(Fallback))
2834 .dispatch_birth(fallback_id, 17, CreationKind::Birth, &mut host)
2835 .await;
2836
2837 let ItemSettlement::Accepted(ChildChoice::Head(ChildCreationOutcome::Established(primary))) =
2838 primary
2839 else {
2840 panic!("expected the primary child result");
2841 };
2842 assert_eq!(primary.id(), primary_id);
2843 let ItemSettlement::Accepted(ChildChoice::Tail(ChildChoice::Head(
2844 ChildCreationOutcome::Established(fallback),
2845 ))) = fallback
2846 else {
2847 panic!("expected the fallback child result");
2848 };
2849 assert_eq!(fallback.id(), fallback_id);
2850
2851 assert_eq!(
2852 host.0,
2853 [
2854 SharedCreation::Primary(primary_id, 11),
2855 SharedCreation::Fallback(fallback_id, 17),
2856 ]
2857 );
2858 }
2859
2860 #[test]
2861 fn birth_protocol_projection_recurses_without_inspecting_send_lanes() {
2862 type Protocols = <Primary as BirthProtocols>::Protocols;
2863 type Expected = BirthProtocol<SharedProtocol, BirthProtocol<Child, NoBirthProtocols>>;
2864
2865 trait Same<T> {}
2866 impl<T> Same<T> for T {}
2867 fn exact<T: Same<Expected>>() {}
2868 exact::<Protocols>();
2869 }
2870 fn child_request_loan_is_affine<Item, Observation>(
2871 request: Item,
2872 duplicate: Item,
2873 reason: Item::Rejection,
2874 observe: impl Fn(&Item) -> Observation,
2875 ) where
2876 Item: ActionItem<
2877 Custody = (Option<Item>, Option<<Item as ActionItem>::Reply>),
2878 Reply = ItemSettlement<
2879 Item,
2880 <Item as ActionItem>::Accepted,
2881 <Item as ActionItem>::Rejection,
2882 <Item as ActionItem>::Prerequisite,
2883 >,
2884 > + 'static,
2885 for<'a> Item: ActionItem<Input<'a> = &'a mut Option<Item>>,
2886 Item::Rejection: Copy + PartialEq + core::fmt::Debug,
2887 Observation: PartialEq + core::fmt::Debug,
2888 {
2889 let expected = observe(&request);
2890 let mut progress = Some(InterpretationProgress::Original(request));
2891 Item::prepare_interpretation(&mut progress);
2892 Item::prepare_interpretation(&mut progress);
2893 let Some(InterpretationProgress::Interpreting(custody)) = &mut progress else {
2894 panic!("preparation must preserve the real request in outside custody");
2895 };
2896 let (input, reply) = Item::interpretation_input(custody)
2897 .expect("one unreplied request must loan its complete input");
2898 let request = input.take().expect("the loan owns the complete request");
2899 let observed = observe(&request);
2900 assert_eq!(
2901 observed, expected,
2902 "the host loan must preserve the complete request"
2903 );
2904 *reply = Some(ItemSettlement::Rejected {
2905 item: request,
2906 reason,
2907 });
2908 let replied = Item::interpretation_input(custody);
2909 assert!(
2910 replied.is_none(),
2911 "a replied request must not be loaned again"
2912 );
2913 custody.0 = Some(duplicate);
2914 let duplicate_loan = Item::interpretation_input(custody);
2915 assert!(
2916 duplicate_loan.is_none(),
2917 "a reply denies reentry even if input is retained"
2918 );
2919 let duplicate = custody
2920 .0
2921 .take()
2922 .expect("the duplicate remains outside-owned");
2923 drop(duplicate);
2924 Item::finish_interpretation(&mut progress);
2925 Item::prepare_interpretation(&mut progress);
2926 Item::finish_interpretation(&mut progress);
2927 match progress {
2928 Some(InterpretationProgress::Completed(Interpretation::Complete(
2929 ItemSettlement::Rejected {
2930 item,
2931 reason: returned_reason,
2932 },
2933 ))) => {
2934 let observed = observe(&item);
2935 assert_eq!(
2936 (observed, returned_reason),
2937 (expected, reason),
2938 "replay must preserve the complete rejected request and reason"
2939 );
2940 }
2941 _ => panic!("completed ownership must survive preparation and finalization replay"),
2942 }
2943 let mut empty = (None, None);
2944 let missing = Item::interpretation_input(&mut empty);
2945 assert!(
2946 missing.is_none(),
2947 "missing input must never expose a host loan"
2948 );
2949 }
2950
2951 impl ChildInputIngress<ChildHead, u8> for User<TestAddr, u8> {
2952 fn child_input(input: u8) -> Self {
2953 User::new(TestAddr(7), input)
2954 }
2955 fn recover_child_input(event: Self) -> Result<u8, Self> {
2956 Ok(event.message)
2957 }
2958 }
2959
2960 type ParentInputWithOuterNotice = EventLayer<Box<str>, EventLayer<u64, User<TestAddr, u8>>>;
2961 type ParentInputWithInnerNotice = EventLayer<u64, EventLayer<Box<str>, User<TestAddr, u8>>>;
2962
2963 #[test]
2964 fn private_input_lifting_preserves_control_in_both_layer_orders() {
2965 let event =
2966 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::child_input(43);
2967 let EventLayer::Inner(EventLayer::Inner(original)) = &event else {
2968 panic!("private input must reach its exact inner user lane");
2969 };
2970 assert_eq!(original, &User::new(TestAddr(7), 43));
2971 let returned =
2972 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
2973 event,
2974 );
2975 assert_eq!(returned, Ok(43));
2976
2977 let event =
2978 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::child_input(47);
2979 let EventLayer::Inner(EventLayer::Inner(original)) = &event else {
2980 panic!("private input must reach the same lane after reordering");
2981 };
2982 assert_eq!(original, &User::new(TestAddr(7), 47));
2983 let returned =
2984 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
2985 event,
2986 );
2987 assert_eq!(returned, Ok(47));
2988 }
2989
2990 #[test]
2991 fn private_input_recovery_returns_each_foreign_owned_lane() {
2992 let notice = Box::<str>::from("outer notice");
2993 let allocation = notice.as_ptr();
2994 let event = ParentInputWithOuterNotice::Owned(notice);
2995 let returned =
2996 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
2997 event,
2998 );
2999 let Err(EventLayer::Owned(returned)) = returned else {
3000 panic!("the outer notice must return in its original lane");
3001 };
3002 assert_eq!(returned.as_ptr(), allocation);
3003 assert_eq!(&*returned, "outer notice");
3004
3005 let event = ParentInputWithOuterNotice::Inner(EventLayer::Owned(37));
3006 let returned =
3007 <ParentInputWithOuterNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
3008 event,
3009 );
3010 assert_eq!(returned, Err(EventLayer::Inner(EventLayer::Owned(37))));
3011
3012 let event = ParentInputWithInnerNotice::Owned(41);
3013 let returned =
3014 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
3015 event,
3016 );
3017 assert_eq!(returned, Err(EventLayer::Owned(41)));
3018
3019 let notice = Box::<str>::from("inner notice");
3020 let allocation = notice.as_ptr();
3021 let event = ParentInputWithInnerNotice::Inner(EventLayer::Owned(notice));
3022 let returned =
3023 <ParentInputWithInnerNotice as ChildInputIngress<ChildHead, u8>>::recover_child_input(
3024 event,
3025 );
3026 let Err(EventLayer::Inner(EventLayer::Owned(returned))) = returned else {
3027 panic!("the reordered inner notice must return in its original lane");
3028 };
3029 assert_eq!(returned.as_ptr(), allocation);
3030 assert_eq!(&*returned, "inner notice");
3031 }
3032
3033 #[test]
3034 fn child_delivery_custody_allows_one_complete_request_and_denies_replay() {
3035 let id = CreationSequence::new()
3036 .issue()
3037 .expect("the creation ID exists");
3038 let request = ChildDelivery::<SharedProtocol, ChildHead>::after(id, 41);
3039 child_request_loan_is_affine(
3040 request,
3041 ChildDelivery::<SharedProtocol, ChildHead>::after(id, 47),
3042 ChildDeliveryReason::ClosedRecipient,
3043 |request| (request.creation, request.message),
3044 );
3045 }
3046
3047 #[test]
3048 fn private_child_input_custody_allows_one_complete_request_and_denies_replay() {
3049 let id = CreationSequence::new()
3050 .issue()
3051 .expect("the creation ID exists");
3052 let request = ChildInput::<Child, ChildHead, u8, ChildHead>::after(id, 43);
3053 child_request_loan_is_affine(
3054 request,
3055 ChildInput::<Child, ChildHead, u8, ChildHead>::after(id, 47),
3056 ChildInputReason::ClosedControlLane,
3057 |request| (request.creation, request.input),
3058 );
3059 }
3060
3061 #[test]
3062 fn creation_route_custody_allows_one_complete_batch_and_denies_replay() {
3063 let id = CreationSequence::new()
3064 .issue()
3065 .expect("the creation ID exists");
3066 let request = Creations::one(CreateChild::<TestAddr, Child>::birth(id, Child));
3067 child_request_loan_is_affine(
3068 request,
3069 Creations::one(CreateChild::<TestAddr, Child>::birth(id, Child)),
3070 ChildNamespaceExhausted,
3071 |request| {
3072 request
3073 .iter()
3074 .map(|creation| (creation.id(), creation.kind(), *creation.child()))
3075 .collect::<Vec<_>>()
3076 },
3077 );
3078 }
3079}