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>
722where
723 C: Behavior,
724 BehaviorAddr<C>: EndpointAddress,
725{
726 Established(CommittedChild<C, Occurrence>),
728 InitializationRejected {
730 creation: RoutedCreation<BehaviorAddr<C>, C>,
732 error: C::Error,
734 },
735 InitializationPanicked {
740 creation: RoutedCreation<BehaviorAddr<C>, C>,
742 },
743 HostRejected {
745 creation: RoutedCreation<BehaviorAddr<C>, C>,
747 initialization: Actions<BehaviorAddr<C>, C::Ph, C::Sends, C::Birth>,
749 reason: CreationRejection,
751 },
752}
753
754impl<C, Occurrence> ChildCreationOutcome<C, Occurrence>
755where
756 C: Behavior,
757 BehaviorAddr<C>: EndpointAddress,
758{
759 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, Self> {
769 match self {
770 Self::Established(child) => Ok(child),
771 other => Err(other),
772 }
773 }
774
775 pub fn into_actor(self) -> Result<EstablishedActor<C>, Self> {
780 self.into_committed().map(|child| child.into_parts().2)
781 }
782}
783
784#[must_use = "a child-creation settlement must be admitted or retained"]
792pub struct ChildCreationSettled<C, Occurrence>
793where
794 C: Behavior,
795 BehaviorAddr<C>: EndpointAddress,
796{
797 settlement: SettledItem<
798 RoutedCreation<BehaviorAddr<C>, C>,
799 ItemSettlement<
800 RoutedCreation<BehaviorAddr<C>, C>,
801 ChildCreationOutcome<C, Occurrence>,
802 CreationRejection,
803 Never,
804 >,
805 >,
806}
807
808impl<C, Occurrence> ChildCreationSettled<C, Occurrence>
809where
810 C: Behavior,
811 BehaviorAddr<C>: EndpointAddress,
812{
813 #[must_use]
814 pub const fn new(
815 settlement: SettledItem<
816 RoutedCreation<BehaviorAddr<C>, C>,
817 ItemSettlement<
818 RoutedCreation<BehaviorAddr<C>, C>,
819 ChildCreationOutcome<C, Occurrence>,
820 CreationRejection,
821 Never,
822 >,
823 >,
824 ) -> Self {
825 Self { settlement }
826 }
827
828 #[must_use]
830 pub fn into_settlement(
831 self,
832 ) -> SettledItem<
833 RoutedCreation<BehaviorAddr<C>, C>,
834 ItemSettlement<
835 RoutedCreation<BehaviorAddr<C>, C>,
836 ChildCreationOutcome<C, Occurrence>,
837 CreationRejection,
838 Never,
839 >,
840 > {
841 self.settlement
842 }
843}
844
845impl<C, Occurrence> core::fmt::Debug for ChildCreationSettled<C, Occurrence>
846where
847 C: Behavior,
848 BehaviorAddr<C>: EndpointAddress,
849{
850 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
851 formatter
852 .debug_struct("ChildCreationSettled")
853 .finish_non_exhaustive()
854 }
855}
856
857pub struct CreationCorrelation<P, Occurrence>
880where
881 P: Protocol,
882{
883 id: CreationId,
884 occurrence: PhantomData<fn() -> (P, Occurrence)>,
885}
886
887impl<P, Occurrence> CreationCorrelation<P, Occurrence>
888where
889 P: Protocol,
890{
891 #[must_use]
892 pub const fn new(id: CreationId) -> Self {
893 Self {
894 id,
895 occurrence: PhantomData,
896 }
897 }
898
899 #[must_use]
900 pub const fn id(self) -> CreationId {
901 self.id
902 }
903}
904
905impl<P, Occurrence> Copy for CreationCorrelation<P, Occurrence> where P: Protocol {}
906
907impl<P, Occurrence> Clone for CreationCorrelation<P, Occurrence>
908where
909 P: Protocol,
910{
911 fn clone(&self) -> Self {
912 *self
913 }
914}
915
916impl<P, Occurrence> core::fmt::Debug for CreationCorrelation<P, Occurrence>
917where
918 P: Protocol,
919{
920 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
921 formatter
922 .debug_tuple("CreationCorrelation")
923 .field(&self.id)
924 .finish()
925 }
926}
927
928impl<P, Occurrence> PartialEq for CreationCorrelation<P, Occurrence>
929where
930 P: Protocol,
931{
932 fn eq(&self, other: &Self) -> bool {
933 self.id == other.id
934 }
935}
936
937impl<P, Occurrence> Eq for CreationCorrelation<P, Occurrence> where P: Protocol {}
938
939pub struct ChildDelivery<P, Occurrence>
946where
947 P: Protocol,
948{
949 pub creation: CreationId,
950 pub message: P::Msg,
951 occurrence: PhantomData<fn() -> Occurrence>,
952}
953
954pub struct ChildInput<Child, Source, Input, Occurrence>
967where
968 Child: Behavior,
969{
970 pub creation: CreationId,
972 pub input: Input,
974 marker: PhantomData<fn() -> (Child, Source, Occurrence)>,
975}
976
977#[derive(Clone, Copy, Debug, Eq, PartialEq)]
979pub enum ChildDeliveryReason {
980 MissingBinding,
981 ClosedRecipient,
982}
983
984#[derive(Clone, Copy, Debug, Eq, PartialEq)]
986pub enum ChildInputReason {
987 MissingBinding,
988 ClosedControlLane,
989}
990
991#[derive(Debug, Clone, Copy, PartialEq, Eq)]
998pub struct ChildReport<R> {
999 pub child: CreationId,
1001 pub report: R,
1003}
1004
1005impl<R> ChildReport<R> {
1006 #[must_use]
1008 pub const fn new(child: CreationId, report: R) -> Self {
1009 Self { child, report }
1010 }
1011}
1012
1013impl<R> From<(CreationId, crate::ReportToParent<R>)> for ChildReport<R> {
1014 fn from((child, request): (CreationId, crate::ReportToParent<R>)) -> Self {
1015 Self::new(child, request.into_inner())
1016 }
1017}
1018
1019impl<Child, Source, Input, Occurrence> ChildInput<Child, Source, Input, Occurrence>
1020where
1021 Child: Behavior,
1022 Child::Event: crate::ChildInputIngress<Source, Input>,
1023{
1024 #[must_use]
1026 pub const fn after(creation: CreationId, input: Input) -> Self {
1027 Self {
1028 creation,
1029 input,
1030 marker: PhantomData,
1031 }
1032 }
1033}
1034
1035impl<Child, Source, Input, Occurrence> Clone for ChildInput<Child, Source, Input, Occurrence>
1036where
1037 Child: Behavior,
1038 Input: Clone,
1039{
1040 fn clone(&self) -> Self {
1041 Self {
1042 creation: self.creation,
1043 input: self.input.clone(),
1044 marker: PhantomData,
1045 }
1046 }
1047}
1048
1049impl<P, Occurrence> ChildDelivery<P, Occurrence>
1050where
1051 P: Protocol,
1052{
1053 #[must_use]
1054 pub const fn after(creation: CreationId, message: P::Msg) -> Self {
1055 Self {
1056 creation,
1057 message,
1058 occurrence: PhantomData,
1059 }
1060 }
1061}
1062
1063impl<P, Occurrence> Clone for ChildDelivery<P, Occurrence>
1064where
1065 P: Protocol,
1066 P::Msg: Clone,
1067{
1068 fn clone(&self) -> Self {
1069 Self {
1070 creation: self.creation,
1071 message: self.message.clone(),
1072 occurrence: PhantomData,
1073 }
1074 }
1075}
1076
1077impl<P, Occurrence> ActionItem for ChildDelivery<P, Occurrence>
1078where
1079 P: Protocol,
1080 P::Msg: Send,
1081{
1082 type Custody = (Option<Self>, Option<Self::Reply>);
1083 type Input<'a>
1084 = &'a mut Option<Self>
1085 where
1086 Self: 'a;
1087 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1088
1089 fn prepare_interpretation(
1090 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1091 ) {
1092 prepare_item::<Self>(progress);
1093 }
1094 fn interpretation_input<'a>(
1095 custody: &'a mut Self::Custody,
1096 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1097 where
1098 Self: 'a,
1099 {
1100 let (input, received) = custody;
1101 if input.is_some() && received.is_none() {
1102 Some((input, received))
1103 } else {
1104 None
1105 }
1106 }
1107 fn finish_interpretation(
1108 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1109 ) {
1110 finish_item::<Self>(progress);
1111 }
1112
1113 type Accepted = ();
1114 type Rejection = ChildDeliveryReason;
1115 type Prerequisite = CreationCorrelation<P, Occurrence>;
1116}
1117
1118impl<Child, Source, Input, Occurrence> ActionItem for ChildInput<Child, Source, Input, Occurrence>
1119where
1120 Child: Behavior,
1121 Input: Send,
1122{
1123 type Custody = (Option<Self>, Option<Self::Reply>);
1124 type Input<'a>
1125 = &'a mut Option<Self>
1126 where
1127 Self: 'a;
1128 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
1129
1130 fn prepare_interpretation(
1131 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1132 ) {
1133 prepare_item::<Self>(progress);
1134 }
1135 fn interpretation_input<'a>(
1136 custody: &'a mut Self::Custody,
1137 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
1138 where
1139 Self: 'a,
1140 {
1141 let (input, received) = custody;
1142 if input.is_some() && received.is_none() {
1143 Some((input, received))
1144 } else {
1145 None
1146 }
1147 }
1148 fn finish_interpretation(
1149 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
1150 ) {
1151 finish_item::<Self>(progress);
1152 }
1153
1154 type Accepted = ();
1155 type Rejection = ChildInputReason;
1156 type Prerequisite = CreationCorrelation<Child::Protocol, Occurrence>;
1157}
1158
1159pub trait EstablishChild<Occurrence, C>
1225where
1226 C: Behavior,
1227 BehaviorAddr<C>: EndpointAddress,
1228{
1229 fn establish_child(
1231 &mut self,
1232 creation: RoutedCreation<BehaviorAddr<C>, C>,
1233 ) -> impl Future<
1234 Output = ItemSettlement<
1235 RoutedCreation<BehaviorAddr<C>, C>,
1236 ChildCreationOutcome<C, Occurrence>,
1237 CreationRejection,
1238 Never,
1239 >,
1240 > + Send;
1241}
1242
1243#[doc(hidden)]
1248pub trait ChildCreationProduct<A: Address, Occurrence>: Sized {
1249 type Result;
1250}
1251
1252pub trait DispatchBirth<A: Address, Host>: ChildCreationProduct<A, ChildHead> + Sized {
1261 fn dispatch_birth(
1264 self,
1265 id: CreationId,
1266 route: A::Nonce,
1267 kind: CreationKind,
1268 host: &mut Host,
1269 ) -> impl Future<
1270 Output = ItemSettlement<
1271 RoutedCreation<A, Self>,
1272 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1273 CreationRejection,
1274 Never,
1275 >,
1276 > + Send;
1277}
1278
1279trait CreateSelectedChild<A: Address, Occurrence, Host>:
1280 ChildCreationProduct<A, Occurrence> + Sized
1281{
1282 fn dispatch_birth_at(
1283 self,
1284 id: CreationId,
1285 route: A::Nonce,
1286 kind: CreationKind,
1287 host: &mut Host,
1288 ) -> impl Future<
1289 Output = ItemSettlement<
1290 RoutedCreation<A, Self>,
1291 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1292 CreationRejection,
1293 Never,
1294 >,
1295 > + Send;
1296}
1297
1298impl<A, Child, Host> DispatchBirth<A, Host> for Child
1299where
1300 A: Address,
1301 Child: CreateSelectedChild<A, ChildHead, Host>,
1302{
1303 fn dispatch_birth(
1304 self,
1305 id: CreationId,
1306 route: A::Nonce,
1307 kind: CreationKind,
1308 host: &mut Host,
1309 ) -> impl Future<
1310 Output = ItemSettlement<
1311 RoutedCreation<A, Self>,
1312 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1313 CreationRejection,
1314 Never,
1315 >,
1316 > + Send {
1317 self.dispatch_birth_at(id, route, kind, host)
1318 }
1319}
1320
1321#[derive(Debug, Clone, PartialEq, Eq)]
1405pub enum ChildChoice<Head, Tail> {
1406 Head(Head),
1408 Tail(Tail),
1410}
1411
1412#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1414pub struct ChildHead;
1415
1416#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1418pub struct ChildTail<Position>(PhantomData<fn() -> Position>);
1419
1420pub trait ChildPosition<Children, Child: Behavior>: sealed::ChildPosition {}
1473
1474impl sealed::ChildPosition for ChildHead {}
1475
1476impl<Child: Behavior> ChildPosition<Child, Child> for ChildHead {}
1477
1478impl<Head: Behavior, Tail> ChildPosition<ChildChoice<Head, Tail>, Head> for ChildHead {}
1479
1480impl<Position> sealed::ChildPosition for ChildTail<Position> {}
1481
1482impl<Head, Tail, Position, Child> ChildPosition<ChildChoice<Head, Tail>, Child>
1483 for ChildTail<Position>
1484where
1485 Child: Behavior,
1486 Position: ChildPosition<Tail, Child>,
1487{
1488}
1489
1490pub trait BirthNodeAppend<Tail>: sealed::BirthNode + Sized
1512where
1513 Tail: sealed::BirthNode,
1514{
1515 type Output: sealed::BirthNode;
1518
1519 fn append_prefix(self) -> Self::Output;
1522
1523 fn append_tail(tail: Tail) -> Self::Output;
1525
1526 #[must_use]
1528 fn append_creations<A: Address>(
1529 prefix: Creations<CreateChild<A, Self>>,
1530 tail: Creations<CreateChild<A, Tail>>,
1531 ) -> Creations<CreateChild<A, Self::Output>> {
1532 let mut combined = Vec::with_capacity(prefix.len() + tail.len());
1533 combined.extend(prefix.into_iter().map(|creation| {
1534 let (id, child, kind) = creation.into_parts();
1535 CreateChild::from_parts(id, Self::append_prefix(child), kind)
1536 }));
1537 combined.extend(tail.into_iter().map(|creation| {
1538 let (id, child, kind) = creation.into_parts();
1539 CreateChild::from_parts(id, Self::append_tail(child), kind)
1540 }));
1541 Creations::from_items(combined)
1542 }
1543}
1544
1545impl<Tail> BirthNodeAppend<Tail> for Never
1546where
1547 Tail: sealed::BirthNode,
1548{
1549 type Output = Tail;
1550
1551 fn append_prefix(self) -> Self::Output {
1552 match self {}
1553 }
1554
1555 fn append_tail(tail: Tail) -> Self::Output {
1556 tail
1557 }
1558}
1559
1560impl<Node> BirthNodeAppend<Never> for Node
1561where
1562 Node: sealed::NonEmptyBirthNode,
1563{
1564 type Output = Node;
1565
1566 fn append_prefix(self) -> Self::Output {
1567 self
1568 }
1569
1570 fn append_tail(tail: Never) -> Self::Output {
1571 match tail {}
1572 }
1573}
1574
1575impl<Child, Tail> BirthNodeAppend<Tail> for Child
1576where
1577 Child: Behavior,
1578 Tail: sealed::NonEmptyBirthNode,
1579{
1580 type Output = ChildChoice<Child, Tail>;
1581
1582 fn append_prefix(self) -> Self::Output {
1583 ChildChoice::Head(self)
1584 }
1585
1586 fn append_tail(tail: Tail) -> Self::Output {
1587 ChildChoice::Tail(tail)
1588 }
1589}
1590
1591impl<Head, Rest, Tail> BirthNodeAppend<Tail> for ChildChoice<Head, Rest>
1592where
1593 Head: Behavior,
1594 Rest: sealed::BirthNode + BirthNodeAppend<Tail>,
1595 Tail: sealed::NonEmptyBirthNode,
1596 Rest::Output: sealed::BirthNode,
1597{
1598 type Output = ChildChoice<Head, Rest::Output>;
1599
1600 fn append_prefix(self) -> Self::Output {
1601 match self {
1602 ChildChoice::Head(head) => ChildChoice::Head(head),
1603 ChildChoice::Tail(rest) => ChildChoice::Tail(rest.append_prefix()),
1604 }
1605 }
1606
1607 fn append_tail(tail: Tail) -> Self::Output {
1608 ChildChoice::Tail(Rest::append_tail(tail))
1609 }
1610}
1611
1612impl<Parent: Behavior> ChildOccurrence<Parent> for ChildHead {
1613 type Resolution = StructuralChildOccurrence<Self>;
1614}
1615
1616impl<Parent: Behavior, Position> ChildOccurrence<Parent> for ChildTail<Position> {
1617 type Resolution = StructuralChildOccurrence<Self>;
1618}
1619
1620#[doc(hidden)]
1627pub trait ChildOccurrenceResolution<Parent: Behavior, Occurrence>:
1628 sealed::ChildOccurrenceDescriptor + sealed::OccurrenceResolution<Parent, Occurrence>
1629{
1630}
1631
1632impl<Parent, Occurrence> ChildOccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1633where
1634 Parent: Behavior,
1635 Occurrence: ChildRole<Parent>,
1636{
1637}
1638
1639impl<Parent: Behavior> ChildOccurrenceResolution<Parent, ChildHead>
1640 for StructuralChildOccurrence<ChildHead>
1641{
1642}
1643
1644impl<Parent: Behavior, Position> ChildOccurrenceResolution<Parent, ChildTail<Position>>
1645 for StructuralChildOccurrence<ChildTail<Position>>
1646{
1647}
1648
1649#[doc(hidden)]
1651pub trait ResolveChildOccurrenceDescriptor<Emitter: Behavior, Occurrence>:
1652 sealed::ChildOccurrenceDescriptor + sealed::ResolveDescriptor<Emitter, Occurrence>
1653{
1654 type Child: Behavior;
1655 type Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Self::Child>;
1656}
1657
1658impl<Emitter, Occurrence, Position> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1659 for StructuralChildOccurrence<Position>
1660where
1661 Emitter: Behavior,
1662 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1663 Position: ChildPosition<
1664 <Emitter::Birth as BirthMode>::Child,
1665 <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child,
1666 >,
1667{
1668 type Child = <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child;
1669 type Position = Position;
1670}
1671
1672impl<Emitter, Occurrence> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1673 for DeclaredChildOccurrence
1674where
1675 Emitter:
1676 Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol> + BehaviorBase,
1677 Emitter::Base: Behavior,
1678 Occurrence: ChildRole<Emitter::Base>,
1679 <Emitter::Birth as BirthMode>::Child:
1680 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1681 Occurrence::Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1682{
1683 type Child = Occurrence::Child;
1684 type Position = Occurrence::Position;
1685}
1686
1687#[doc(hidden)]
1689pub trait BirthNodeAt<Position>: sealed::BirthNode {
1690 type Child: Behavior;
1691}
1692
1693impl<Child: Behavior> BirthNodeAt<ChildHead> for Child {
1694 type Child = Child;
1695}
1696
1697impl<Head: Behavior, Tail> BirthNodeAt<ChildHead> for ChildChoice<Head, Tail>
1698where
1699 Tail: sealed::BirthNode,
1700{
1701 type Child = Head;
1702}
1703
1704impl<Head, Tail, Position> BirthNodeAt<ChildTail<Position>> for ChildChoice<Head, Tail>
1705where
1706 Head: Behavior,
1707 Tail: BirthNodeAt<Position>,
1708{
1709 type Child = <Tail as BirthNodeAt<Position>>::Child;
1710}
1711
1712pub trait ChildOccurrenceShape {
1739 type Empty;
1741
1742 type Member<Occurrence, Child: Behavior, Tail>;
1744}
1745
1746pub trait ChildOccurrenceProduct<Shape>: sealed::BirthNode
1773where
1774 Shape: ChildOccurrenceShape,
1775{
1776 type Product;
1778}
1779
1780#[doc(hidden)]
1783pub trait ChildOccurrenceProductAt<Occurrence, Shape>: sealed::BirthNode
1784where
1785 Shape: ChildOccurrenceShape,
1786{
1787 type Product;
1788}
1789
1790impl<Node, Shape> ChildOccurrenceProduct<Shape> for Node
1791where
1792 Node: ChildOccurrenceProductAt<ChildHead, Shape>,
1793 Shape: ChildOccurrenceShape,
1794{
1795 type Product = <Node as ChildOccurrenceProductAt<ChildHead, Shape>>::Product;
1796}
1797
1798impl<Occurrence, Shape, Child> ChildOccurrenceProductAt<Occurrence, Shape> for Child
1799where
1800 Shape: ChildOccurrenceShape,
1801 Child: Behavior,
1802{
1803 type Product = Shape::Member<Occurrence, Child, Shape::Empty>;
1804}
1805
1806impl<Occurrence, Shape, Head, Tail> ChildOccurrenceProductAt<Occurrence, Shape>
1807 for ChildChoice<Head, Tail>
1808where
1809 Shape: ChildOccurrenceShape,
1810 Head: Behavior,
1811 Tail: ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>,
1812{
1813 type Product = Shape::Member<
1814 Occurrence,
1815 Head,
1816 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1817 >;
1818}
1819
1820impl<Occurrence, Shape> ChildOccurrenceProductAt<Occurrence, Shape> for Never
1821where
1822 Shape: ChildOccurrenceShape,
1823{
1824 type Product = Shape::Empty;
1825}
1826
1827pub type ChildOccurrences<Node, Shape> = <Node as ChildOccurrenceProduct<Shape>>::Product;
1829
1830mod sealed {
1831 use super::{
1832 Behavior, BehaviorBase, BirthMode, BirthNodeAt, ChildChoice, ChildHead, ChildOccurrence,
1833 ChildRole, ChildTail, DeclaredChildOccurrence, Never, ResolveChildOccurrenceDescriptor,
1834 StructuralChildOccurrence,
1835 };
1836
1837 pub trait BirthNode {}
1838
1839 pub trait NonEmptyBirthNode: BirthNode {}
1840
1841 impl<Child: Behavior> BirthNode for Child {}
1842 impl<Child: Behavior> NonEmptyBirthNode for Child {}
1843
1844 impl<Head, Tail> BirthNode for ChildChoice<Head, Tail>
1845 where
1846 Head: Behavior,
1847 Tail: BirthNode,
1848 {
1849 }
1850
1851 impl<Head, Tail> NonEmptyBirthNode for ChildChoice<Head, Tail>
1852 where
1853 Head: Behavior,
1854 Tail: BirthNode,
1855 {
1856 }
1857
1858 impl BirthNode for Never {}
1859
1860 pub trait ChildPosition {}
1861 pub trait ChildProduct {}
1862
1863 pub trait ChildOccurrenceDescriptor {}
1864
1865 impl ChildOccurrenceDescriptor for DeclaredChildOccurrence {}
1866
1867 impl<Position> ChildOccurrenceDescriptor for StructuralChildOccurrence<Position> {}
1868
1869 pub trait OccurrenceResolution<Parent: Behavior, Occurrence> {}
1870
1871 impl<Parent, Occurrence> OccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1872 where
1873 Parent: Behavior,
1874 Occurrence: ChildRole<Parent>,
1875 {
1876 }
1877
1878 impl<Parent: Behavior> OccurrenceResolution<Parent, ChildHead>
1879 for StructuralChildOccurrence<ChildHead>
1880 {
1881 }
1882
1883 impl<Parent: Behavior, Position> OccurrenceResolution<Parent, ChildTail<Position>>
1884 for StructuralChildOccurrence<ChildTail<Position>>
1885 {
1886 }
1887
1888 pub trait ResolveDescriptor<Emitter: Behavior, Occurrence> {}
1889
1890 impl<Emitter, Occurrence, Position> ResolveDescriptor<Emitter, Occurrence>
1891 for StructuralChildOccurrence<Position>
1892 where
1893 Emitter: Behavior,
1894 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1895 {
1896 }
1897
1898 impl<Emitter, Occurrence> ResolveDescriptor<Emitter, Occurrence> for DeclaredChildOccurrence
1899 where
1900 Emitter: Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol>
1901 + BehaviorBase,
1902 Emitter::Base: Behavior,
1903 Occurrence: ChildRole<Emitter::Base>,
1904 <Emitter::Birth as BirthMode>::Child:
1905 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1906 Occurrence::Position:
1907 super::ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1908 {
1909 }
1910
1911 pub trait ResolveChildOccurrence<Occurrence> {}
1912
1913 impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
1914 where
1915 Emitter: Behavior + BehaviorBase,
1916 Emitter::Base: Behavior,
1917 Occurrence: ChildOccurrence<Emitter::Base>,
1918 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
1919 {
1920 }
1921}
1922
1923#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1925pub struct NoChildren;
1926
1927impl sealed::ChildProduct for NoChildren {}
1928
1929pub struct ChildCons<A: Address, C, Earlier> {
1931 creation: CreateChild<A, C>,
1932 earlier: Earlier,
1933}
1934
1935impl<A: Address, C, Earlier> sealed::ChildProduct for ChildCons<A, C, Earlier> {}
1936
1937pub struct Children<A: Address, Product = NoChildren> {
1943 product: Product,
1944 address: PhantomData<fn() -> A>,
1945}
1946
1947pub trait ChildProduct<A: Address>: sealed::ChildProduct + Sized {
1949 type Choice: BirthNodeAppend<Never>;
1951
1952 #[doc(hidden)]
1953 fn stage(self) -> Vec<CreateChild<A, Self::Choice>>;
1954}
1955
1956impl<A: Address> ChildProduct<A> for NoChildren {
1957 type Choice = Never;
1958
1959 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1960 Vec::new()
1961 }
1962}
1963
1964impl<A, C, Earlier> ChildProduct<A> for ChildCons<A, C, Earlier>
1965where
1966 A: Address,
1967 C: Behavior,
1968 C::Protocol: Protocol<Addr = A>,
1969 Earlier: ChildProduct<A>,
1970{
1971 type Choice = ChildChoice<C, Earlier::Choice>;
1972
1973 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1974 let earlier = self.earlier.stage();
1975 let mut creates = earlier
1976 .into_iter()
1977 .map(|creation| {
1978 let (id, child, kind) = creation.into_parts();
1979 CreateChild::from_parts(id, ChildChoice::Tail(child), kind)
1980 })
1981 .collect::<Vec<_>>();
1982 let (id, child, kind) = self.creation.into_parts();
1983 creates.push(CreateChild::from_parts(id, ChildChoice::Head(child), kind));
1984 creates
1985 }
1986}
1987
1988impl<A: Address> Children<A, NoChildren> {
1989 #[must_use]
1991 pub const fn new() -> Self {
1992 Self {
1993 product: NoChildren,
1994 address: PhantomData,
1995 }
1996 }
1997}
1998
1999impl<A: Address> Default for Children<A, NoChildren> {
2000 fn default() -> Self {
2001 Self::new()
2002 }
2003}
2004
2005impl<A: Address, Product> Children<A, Product> {
2006 #[must_use]
2008 pub fn create<C>(self, creation: CreateChild<A, C>) -> Children<A, ChildCons<A, C, Product>>
2009 where
2010 C: Behavior,
2011 C::Protocol: Protocol<Addr = A>,
2012 {
2013 Children {
2014 product: ChildCons {
2015 creation,
2016 earlier: self.product,
2017 },
2018 address: PhantomData,
2019 }
2020 }
2021
2022 #[must_use]
2024 pub fn child<C>(self, id: CreationId, child: C) -> Children<A, ChildCons<A, C, Product>>
2025 where
2026 C: Behavior,
2027 C::Protocol: Protocol<Addr = A>,
2028 {
2029 self.create(CreateChild::birth(id, child))
2030 }
2031}
2032
2033impl<A, Product> Children<A, Product>
2034where
2035 A: Address,
2036 Product: ChildProduct<A>,
2037{
2038 #[must_use]
2040 pub fn into_creates(self) -> Creations<CreateChild<A, Product::Choice>> {
2041 Creations::from_items(self.product.stage())
2042 }
2043}
2044
2045impl<A, Occurrence, Head, Tail> ChildCreationProduct<A, Occurrence> for ChildChoice<Head, Tail>
2046where
2047 A: EndpointAddress,
2048 Head: Behavior,
2049 Head::Protocol: Protocol<Addr = A>,
2050 Tail: ChildCreationProduct<A, ChildTail<Occurrence>>,
2051{
2052 type Result = ChildChoice<
2053 ChildCreationOutcome<Head, Occurrence>,
2054 <Tail as ChildCreationProduct<A, ChildTail<Occurrence>>>::Result,
2055 >;
2056}
2057
2058impl<A, Occurrence, Head, Tail, Host> CreateSelectedChild<A, Occurrence, Host>
2059 for ChildChoice<Head, Tail>
2060where
2061 A: EndpointAddress,
2062 A::Nonce: Send,
2063 Head: Behavior + Send,
2064 Head::Protocol: Protocol<Addr = A>,
2065 Tail: CreateSelectedChild<A, ChildTail<Occurrence>, Host> + Send,
2066 Host: EstablishChild<Occurrence, Head> + Send,
2067{
2068 async fn dispatch_birth_at(
2069 self,
2070 id: CreationId,
2071 route: A::Nonce,
2072 kind: CreationKind,
2073 host: &mut Host,
2074 ) -> ItemSettlement<
2075 RoutedCreation<A, Self>,
2076 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2077 CreationRejection,
2078 Never,
2079 > {
2080 match self {
2081 Self::Head(child) => {
2082 let creation = RoutedCreation::new(CreateChild::from_parts(id, child, kind), route);
2083 match host.establish_child(creation).await {
2084 ItemSettlement::Accepted(receipt) => {
2085 ItemSettlement::Accepted(ChildChoice::Head(receipt))
2086 }
2087 ItemSettlement::Rejected { item, reason } => {
2088 let (creation, route) = item.into_parts();
2089 let (id, child, kind) = creation.into_parts();
2090 ItemSettlement::Rejected {
2091 item: RoutedCreation::new(
2092 CreateChild::from_parts(id, Self::Head(child), kind),
2093 route,
2094 ),
2095 reason,
2096 }
2097 }
2098 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2099 ItemSettlement::Corrupt { item, fault } => {
2100 let (creation, route) = item.into_parts();
2101 let (id, child, kind) = creation.into_parts();
2102 ItemSettlement::Corrupt {
2103 item: RoutedCreation::new(
2104 CreateChild::from_parts(id, Self::Head(child), kind),
2105 route,
2106 ),
2107 fault,
2108 }
2109 }
2110 }
2111 }
2112 Self::Tail(tail) => match tail.dispatch_birth_at(id, route, kind, host).await {
2113 ItemSettlement::Accepted(receipt) => {
2114 ItemSettlement::Accepted(ChildChoice::Tail(receipt))
2115 }
2116 ItemSettlement::Rejected { item, reason } => {
2117 let (creation, route) = item.into_parts();
2118 let (id, child, kind) = creation.into_parts();
2119 ItemSettlement::Rejected {
2120 item: RoutedCreation::new(
2121 CreateChild::from_parts(id, Self::Tail(child), kind),
2122 route,
2123 ),
2124 reason,
2125 }
2126 }
2127 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2128 ItemSettlement::Corrupt { item, fault } => {
2129 let (creation, route) = item.into_parts();
2130 let (id, child, kind) = creation.into_parts();
2131 ItemSettlement::Corrupt {
2132 item: RoutedCreation::new(
2133 CreateChild::from_parts(id, Self::Tail(child), kind),
2134 route,
2135 ),
2136 fault,
2137 }
2138 }
2139 },
2140 }
2141 }
2142}
2143
2144impl<A, Occurrence> ChildCreationProduct<A, Occurrence> for Never
2145where
2146 A: Address,
2147{
2148 type Result = Never;
2149}
2150
2151impl<A, Occurrence, Host> CreateSelectedChild<A, Occurrence, Host> for Never
2152where
2153 A: Address,
2154{
2155 fn dispatch_birth_at(
2156 self,
2157 _id: CreationId,
2158 _route: A::Nonce,
2159 _kind: CreationKind,
2160 _host: &mut Host,
2161 ) -> impl Future<
2162 Output = ItemSettlement<
2163 RoutedCreation<A, Self>,
2164 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2165 CreationRejection,
2166 Never,
2167 >,
2168 > + Send {
2169 async move { match self {} }
2170 }
2171}
2172
2173impl<A, Occurrence, C> ChildCreationProduct<A, Occurrence> for C
2174where
2175 A: EndpointAddress,
2176 C: Behavior,
2177 C::Protocol: Protocol<Addr = A>,
2178{
2179 type Result = ChildCreationOutcome<C, Occurrence>;
2180}
2181
2182impl<A, Occurrence, C, Host> CreateSelectedChild<A, Occurrence, Host> for C
2183where
2184 A: EndpointAddress,
2185 C: Behavior,
2186 C::Protocol: Protocol<Addr = A>,
2187 Host: EstablishChild<Occurrence, C>,
2188{
2189 fn dispatch_birth_at(
2190 self,
2191 id: CreationId,
2192 route: A::Nonce,
2193 kind: CreationKind,
2194 host: &mut Host,
2195 ) -> impl Future<
2196 Output = ItemSettlement<
2197 RoutedCreation<A, Self>,
2198 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2199 CreationRejection,
2200 Never,
2201 >,
2202 > + Send {
2203 host.establish_child(RoutedCreation::new(
2204 CreateChild::from_parts(id, self, kind),
2205 route,
2206 ))
2207 }
2208}
2209
2210pub trait BirthMode {
2212 type Child;
2213}
2214
2215pub struct NoBirthProtocols;
2217
2218pub struct BirthProtocol<P: Protocol, Tail> {
2220 protocol: PhantomData<fn() -> P>,
2221 tail: PhantomData<fn() -> Tail>,
2222}
2223
2224pub struct BirthProtocolHead;
2226
2227pub struct BirthProtocolTail<Position>(PhantomData<fn() -> Position>);
2229
2230pub trait BirthProtocolAt<P: Protocol, Position> {}
2232
2233impl<P: Protocol, Tail> BirthProtocolAt<P, BirthProtocolHead> for BirthProtocol<P, Tail> {}
2234
2235impl<Head, Tail, P, Position> BirthProtocolAt<P, BirthProtocolTail<Position>>
2236 for BirthProtocol<Head, Tail>
2237where
2238 Head: Protocol,
2239 P: Protocol,
2240 Tail: BirthProtocolAt<P, Position>,
2241{
2242}
2243
2244pub trait BirthProtocolProduct {
2246 type Append<Tail: BirthProtocolProduct>: BirthProtocolProduct;
2247}
2248
2249impl BirthProtocolProduct for NoBirthProtocols {
2250 type Append<Tail: BirthProtocolProduct> = Tail;
2251}
2252
2253impl<P, Rest> BirthProtocolProduct for BirthProtocol<P, Rest>
2254where
2255 P: Protocol,
2256 Rest: BirthProtocolProduct,
2257{
2258 type Append<Tail: BirthProtocolProduct> = BirthProtocol<P, Rest::Append<Tail>>;
2259}
2260
2261pub trait BirthProtocols: Behavior {
2267 type Protocols: BirthProtocolProduct;
2268}
2269
2270impl<B> BirthProtocols for B
2271where
2272 B: Behavior,
2273 B::Birth: BirthModeProtocols,
2274{
2275 type Protocols = BirthProtocol<B::Protocol, <B::Birth as BirthModeProtocols>::Protocols>;
2276}
2277
2278#[doc(hidden)]
2279pub trait BirthModeProtocols {
2280 type Protocols: BirthProtocolProduct;
2281}
2282
2283impl<M> BirthModeProtocols for M
2284where
2285 M: BirthMode,
2286 M::Child: BirthNodeProtocols,
2287{
2288 type Protocols = <M::Child as BirthNodeProtocols>::Protocols;
2289}
2290
2291#[doc(hidden)]
2292pub trait BirthNodeProtocols {
2293 type Protocols: BirthProtocolProduct;
2294}
2295
2296impl<B> BirthNodeProtocols for B
2297where
2298 B: BirthProtocols,
2299{
2300 type Protocols = B::Protocols;
2301}
2302
2303impl<Head, Tail> BirthNodeProtocols for ChildChoice<Head, Tail>
2304where
2305 Head: BirthNodeProtocols,
2306 Tail: BirthNodeProtocols,
2307{
2308 type Protocols = <Head::Protocols as BirthProtocolProduct>::Append<Tail::Protocols>;
2309}
2310
2311impl BirthNodeProtocols for Never {
2312 type Protocols = NoBirthProtocols;
2313}
2314
2315#[doc(hidden)]
2320pub trait BirthNodeLogicalHosts {
2321 type LogicalHosts: BirthProtocolProduct;
2322}
2323
2324impl<B> BirthNodeLogicalHosts for B
2325where
2326 B: crate::LogicalHostRequirements,
2327{
2328 type LogicalHosts = B::LogicalHosts;
2329}
2330
2331impl<Head, Tail> BirthNodeLogicalHosts for ChildChoice<Head, Tail>
2332where
2333 Head: BirthNodeLogicalHosts,
2334 Tail: BirthNodeLogicalHosts,
2335{
2336 type LogicalHosts = <Head::LogicalHosts as BirthProtocolProduct>::Append<Tail::LogicalHosts>;
2337}
2338
2339impl BirthNodeLogicalHosts for Never {
2340 type LogicalHosts = NoBirthProtocols;
2341}
2342
2343#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2345pub struct NoBirths;
2346
2347impl BirthMode for NoBirths {
2348 type Child = Never;
2349}
2350
2351#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2353pub struct Births<C>(PhantomData<fn() -> C>);
2354
2355impl<C> BirthMode for Births<C> {
2356 type Child = C;
2357}
2358
2359#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2367pub struct RetirementBirths<C>(PhantomData<fn() -> C>);
2368
2369impl<C> BirthMode for RetirementBirths<C> {
2370 type Child = C;
2371}
2372
2373#[cfg(test)]
2374mod tests {
2375 use super::*;
2376 use crate::{Actions, BehaviorActed, ChildInputIngress, Interpretation, NoBirths, User};
2377
2378 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2379 struct TestAddr(u64);
2380
2381 impl Address for TestAddr {
2382 type Nonce = u64;
2383 }
2384
2385 struct TestEndpoint<P>(PhantomData<fn() -> P>);
2386
2387 impl<P> Clone for TestEndpoint<P> {
2388 fn clone(&self) -> Self {
2389 *self
2390 }
2391 }
2392
2393 impl<P> Copy for TestEndpoint<P> {}
2394
2395 struct TestInstalled<B: Behavior> {
2396 endpoint: TestEndpoint<B::Protocol>,
2397 control: std::sync::mpsc::Sender<B::Event>,
2398 }
2399
2400 impl<B: Behavior> Clone for TestInstalled<B> {
2401 fn clone(&self) -> Self {
2402 Self {
2403 endpoint: self.endpoint,
2404 control: self.control.clone(),
2405 }
2406 }
2407 }
2408
2409 impl EndpointAddress for TestAddr {
2410 type Established<P>
2411 = TestEndpoint<P>
2412 where
2413 P: Protocol<Addr = Self>;
2414
2415 type Installed<B>
2416 = TestInstalled<B>
2417 where
2418 B: Behavior<Protocol: Protocol<Addr = Self>>;
2419
2420 fn recipient<B>(installed: &Self::Installed<B>) -> Self::Established<B::Protocol>
2421 where
2422 B: Behavior<Protocol: Protocol<Addr = Self>>,
2423 {
2424 installed.endpoint
2425 }
2426 }
2427
2428 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2429 struct Child;
2430
2431 struct SharedProtocol;
2432
2433 impl behavior::Protocol for SharedProtocol {
2434 type Addr = TestAddr;
2435 type Msg = u8;
2436 }
2437
2438 struct Primary;
2439 struct Fallback;
2440
2441 macro_rules! shared_protocol_behavior {
2442 ($behavior:ty, $birth:ty) => {
2443 impl Behavior for $behavior {
2444 type Protocol = SharedProtocol;
2445 type Event = User<TestAddr, u8>;
2446 type Sends = Vec<Never>;
2447 type Ph = Never;
2448 type Error = Never;
2449 type Birth = $birth;
2450
2451 fn transition(
2452 &mut self,
2453 _: crate::ActiveTurn,
2454 _: Self::Event,
2455 ) -> BehaviorActed<Self> {
2456 Ok(Actions::cont())
2457 }
2458 }
2459 };
2460 }
2461
2462 shared_protocol_behavior!(Primary, Births<Child>);
2463 shared_protocol_behavior!(Fallback, NoBirths);
2464
2465 impl behavior::Protocol for Child {
2466 type Addr = TestAddr;
2467 type Msg = u8;
2468 }
2469
2470 impl Behavior for Child {
2471 type Protocol = Self;
2472 type Event = User<TestAddr, u8>;
2473 type Sends = Vec<Never>;
2474 type Ph = Never;
2475 type Error = Never;
2476 type Birth = NoBirths;
2477
2478 fn transition(&mut self, _: crate::ActiveTurn, _: Self::Event) -> BehaviorActed<Self> {
2479 Ok(Actions::cont())
2480 }
2481 }
2482
2483 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2484 enum ChildPlan {
2485 CreateChild,
2486 RejectBeforeTransfer,
2487 }
2488
2489 struct RecordingHost {
2490 calls: usize,
2491 observed: Vec<(CreationId, u64, CreationKind)>,
2492 plan: ChildPlan,
2493 control_receivers: Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2494 }
2495
2496 #[derive(Debug, PartialEq, Eq)]
2497 enum SharedCreation {
2498 Primary(CreationId, u64),
2499 Fallback(CreationId, u64),
2500 }
2501
2502 #[derive(Default)]
2503 struct SharedProtocolHost(
2504 Vec<SharedCreation>,
2505 Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2506 );
2507
2508 impl EstablishChild<ChildHead, Primary> for SharedProtocolHost {
2509 async fn establish_child(
2510 &mut self,
2511 creation: RoutedCreation<TestAddr, Primary>,
2512 ) -> ItemSettlement<
2513 RoutedCreation<TestAddr, Primary>,
2514 ChildCreationOutcome<Primary, ChildHead>,
2515 CreationRejection,
2516 Never,
2517 > {
2518 let id = creation.id();
2519 let kind = creation.kind();
2520 let route = creation.route();
2521 let (creation, _) = creation.into_parts();
2522 let (_, _child, _) = creation.into_parts();
2523 self.0.push(SharedCreation::Primary(id, route));
2524 let (control, receiver) = std::sync::mpsc::channel();
2525 self.1.push(receiver);
2526 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2527 id,
2528 kind,
2529 EstablishedActor::issued(TestInstalled {
2530 endpoint: TestEndpoint(PhantomData),
2531 control,
2532 }),
2533 )))
2534 }
2535 }
2536
2537 impl EstablishChild<ChildTail<ChildHead>, Fallback> for SharedProtocolHost {
2538 async fn establish_child(
2539 &mut self,
2540 creation: RoutedCreation<TestAddr, Fallback>,
2541 ) -> ItemSettlement<
2542 RoutedCreation<TestAddr, Fallback>,
2543 ChildCreationOutcome<Fallback, ChildTail<ChildHead>>,
2544 CreationRejection,
2545 Never,
2546 > {
2547 let id = creation.id();
2548 let kind = creation.kind();
2549 let route = creation.route();
2550 let (creation, _) = creation.into_parts();
2551 let (_, _child, _) = creation.into_parts();
2552 self.0.push(SharedCreation::Fallback(id, route));
2553 let (control, receiver) = std::sync::mpsc::channel();
2554 self.1.push(receiver);
2555 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2556 id,
2557 kind,
2558 EstablishedActor::issued(TestInstalled {
2559 endpoint: TestEndpoint(PhantomData),
2560 control,
2561 }),
2562 )))
2563 }
2564 }
2565
2566 impl EstablishChild<ChildHead, Child> for RecordingHost {
2567 async fn establish_child(
2568 &mut self,
2569 creation: RoutedCreation<TestAddr, Child>,
2570 ) -> ItemSettlement<
2571 RoutedCreation<TestAddr, Child>,
2572 ChildCreationOutcome<Child, ChildHead>,
2573 CreationRejection,
2574 Never,
2575 > {
2576 self.calls += 1;
2577 self.observed
2578 .push((creation.id(), creation.route(), creation.kind()));
2579 match self.plan {
2580 ChildPlan::CreateChild => {
2581 let id = creation.id();
2582 let kind = creation.kind();
2583 let (creation, _) = creation.into_parts();
2584 let (_, _child, _) = creation.into_parts();
2585 let (control, receiver) = std::sync::mpsc::channel();
2586 self.control_receivers.push(receiver);
2587 ItemSettlement::Accepted(ChildCreationOutcome::Established(
2588 CommittedChild::new(
2589 id,
2590 kind,
2591 EstablishedActor::issued(TestInstalled {
2592 endpoint: TestEndpoint(PhantomData),
2593 control,
2594 }),
2595 ),
2596 ))
2597 }
2598 ChildPlan::RejectBeforeTransfer => ItemSettlement::Rejected {
2599 item: creation,
2600 reason: CreationRejection::EnvironmentFailed,
2601 },
2602 }
2603 }
2604 }
2605
2606 fn host(plan: ChildPlan) -> RecordingHost {
2607 RecordingHost {
2608 calls: 0,
2609 observed: Vec::new(),
2610 plan,
2611 control_receivers: Vec::new(),
2612 }
2613 }
2614
2615 fn assert_send<T: Send>(_: &T) {}
2616
2617 #[test]
2618 fn empty_child_product_stages_no_creations() {
2619 let creations = <NoChildren as ChildProduct<TestAddr>>::stage(NoChildren);
2620 assert!(creations.is_empty());
2621 }
2622
2623 #[test]
2624 fn creation_values_preserve_ids_order_and_debug_identity() {
2625 let mut sequence = CreationSequence::new();
2626 let first = sequence.issue().expect("the first creation ID exists");
2627 let second = sequence.issue().expect("the second creation ID exists");
2628 assert_eq!(first.get(), 1);
2629 assert_eq!(second.get(), 2);
2630
2631 let first_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2632 let same_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2633 let second_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(second);
2634 assert_eq!(first_correlation, same_correlation);
2635 assert_ne!(first_correlation, second_correlation);
2636 assert_eq!(
2637 format!("{first_correlation:?}"),
2638 "CreationCorrelation(CreationId(1))"
2639 );
2640
2641 let mut creations = Creations::one(1_u8);
2642 creations.extend([2, 3]);
2643 assert_eq!(creations.len(), 3);
2644 assert!(!creations.is_empty());
2645 assert_eq!(creations.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
2646 let borrowed = (&creations).into_iter().copied().collect::<Vec<_>>();
2647 assert_eq!(borrowed, [1, 2, 3]);
2648
2649 let collected: Creations<_> = [4_u8, 5].into_iter().collect();
2650 assert_eq!(collected.len(), 2);
2651 let collected_values = collected.into_iter().collect::<Vec<_>>();
2652 assert_eq!(collected_values, [4, 5]);
2653
2654 let returned = ChildCreationSettled::<Child, ChildHead>::new(SettledItem::Unattempted(
2655 RoutedCreation::new(CreateChild::birth(first, Child), 17),
2656 ));
2657 assert_eq!(format!("{returned:?}"), "ChildCreationSettled { .. }");
2658 }
2659
2660 #[tokio::test]
2661 async fn concrete_child_dispatches_once_with_exact_creation_and_route() {
2662 let mut sequence = CreationSequence::new();
2663 let previous = sequence.issue().expect("the previous ID exists");
2664 let id = sequence.issue().expect("the replacement ID exists");
2665 let mut host = host(ChildPlan::CreateChild);
2666 let kind = CreationKind::replacement(previous);
2667 let future = Child.dispatch_birth(id, 17, kind, &mut host);
2668 assert_send(&future);
2669 let result = future.await;
2670
2671 let ItemSettlement::Accepted(ChildCreationOutcome::Established(established)) = result
2672 else {
2673 panic!("expected the child to be created");
2674 };
2675 assert_eq!(established.id(), id);
2676 assert_eq!(host.calls, 1);
2677 assert_eq!(host.observed, [(id, 17, kind)]);
2678 }
2679
2680 #[tokio::test]
2681 async fn concrete_child_returns_the_exact_rejected_creation_without_retry() {
2682 let mut sequence = CreationSequence::new();
2683 let previous = sequence.issue().expect("the previous ID exists");
2684 let id = sequence.issue().expect("the replacement ID exists");
2685 let mut host = host(ChildPlan::RejectBeforeTransfer);
2686 let kind = CreationKind::replacement(previous);
2687 let future = Child.dispatch_birth(id, 23, kind, &mut host);
2688 assert_send(&future);
2689 let result = future.await;
2690
2691 let ItemSettlement::Rejected { item, reason } = result else {
2692 panic!("expected refusal before child ownership transfer");
2693 };
2694 assert_eq!(
2695 item,
2696 RoutedCreation::new(CreateChild::replacement(id, previous, Child), 23)
2697 );
2698 assert_eq!(reason, CreationRejection::EnvironmentFailed);
2699 assert_eq!(host.calls, 1);
2700 assert_eq!(host.observed, [(id, 23, kind)]);
2701 }
2702
2703 #[tokio::test]
2704 async fn distinct_child_alternatives_preserve_one_canonical_protocol_identity() {
2705 type Alternatives = ChildChoice<Primary, ChildChoice<Fallback, Never>>;
2706
2707 fn requires_shared_protocol<C: Behavior<Protocol = SharedProtocol>>() {}
2708 requires_shared_protocol::<Primary>();
2709 requires_shared_protocol::<Fallback>();
2710
2711 let mut sequence = CreationSequence::new();
2712 let primary_id = sequence.issue().expect("the primary ID exists");
2713 let fallback_id = sequence.issue().expect("the fallback ID exists");
2714 let mut host = SharedProtocolHost::default();
2715 let primary = Alternatives::Head(Primary)
2716 .dispatch_birth(primary_id, 11, CreationKind::Birth, &mut host)
2717 .await;
2718 let fallback = Alternatives::Tail(ChildChoice::Head(Fallback))
2719 .dispatch_birth(fallback_id, 17, CreationKind::Birth, &mut host)
2720 .await;
2721
2722 let ItemSettlement::Accepted(ChildChoice::Head(ChildCreationOutcome::Established(primary))) =
2723 primary
2724 else {
2725 panic!("expected the primary child result");
2726 };
2727 assert_eq!(primary.id(), primary_id);
2728 let ItemSettlement::Accepted(ChildChoice::Tail(ChildChoice::Head(
2729 ChildCreationOutcome::Established(fallback),
2730 ))) = fallback
2731 else {
2732 panic!("expected the fallback child result");
2733 };
2734 assert_eq!(fallback.id(), fallback_id);
2735
2736 assert_eq!(
2737 host.0,
2738 [
2739 SharedCreation::Primary(primary_id, 11),
2740 SharedCreation::Fallback(fallback_id, 17),
2741 ]
2742 );
2743 }
2744
2745 #[test]
2746 fn birth_protocol_projection_recurses_without_inspecting_send_lanes() {
2747 type Protocols = <Primary as BirthProtocols>::Protocols;
2748 type Expected = BirthProtocol<SharedProtocol, BirthProtocol<Child, NoBirthProtocols>>;
2749
2750 trait Same<T> {}
2751 impl<T> Same<T> for T {}
2752 fn exact<T: Same<Expected>>() {}
2753 exact::<Protocols>();
2754 }
2755 fn child_request_loan_is_affine<Item, Observation>(
2756 request: Item,
2757 duplicate: Item,
2758 reason: Item::Rejection,
2759 observe: impl Fn(&Item) -> Observation,
2760 ) where
2761 Item: ActionItem<
2762 Custody = (Option<Item>, Option<<Item as ActionItem>::Reply>),
2763 Reply = ItemSettlement<
2764 Item,
2765 <Item as ActionItem>::Accepted,
2766 <Item as ActionItem>::Rejection,
2767 <Item as ActionItem>::Prerequisite,
2768 >,
2769 > + 'static,
2770 for<'a> Item: ActionItem<Input<'a> = &'a mut Option<Item>>,
2771 Item::Rejection: Copy + PartialEq + core::fmt::Debug,
2772 Observation: PartialEq + core::fmt::Debug,
2773 {
2774 let expected = observe(&request);
2775 let mut progress = Some(InterpretationProgress::Original(request));
2776 Item::prepare_interpretation(&mut progress);
2777 Item::prepare_interpretation(&mut progress);
2778 let Some(InterpretationProgress::Interpreting(custody)) = &mut progress else {
2779 panic!("preparation must preserve the real request in outside custody");
2780 };
2781 let (input, reply) = Item::interpretation_input(custody)
2782 .expect("one unreplied request must loan its complete input");
2783 let request = input.take().expect("the loan owns the complete request");
2784 let observed = observe(&request);
2785 assert_eq!(
2786 observed, expected,
2787 "the host loan must preserve the complete request"
2788 );
2789 *reply = Some(ItemSettlement::Rejected {
2790 item: request,
2791 reason,
2792 });
2793 let replied = Item::interpretation_input(custody);
2794 assert!(
2795 replied.is_none(),
2796 "a replied request must not be loaned again"
2797 );
2798 custody.0 = Some(duplicate);
2799 let duplicate_loan = Item::interpretation_input(custody);
2800 assert!(
2801 duplicate_loan.is_none(),
2802 "a reply denies reentry even if input is retained"
2803 );
2804 let duplicate = custody
2805 .0
2806 .take()
2807 .expect("the duplicate remains outside-owned");
2808 drop(duplicate);
2809 Item::finish_interpretation(&mut progress);
2810 Item::prepare_interpretation(&mut progress);
2811 Item::finish_interpretation(&mut progress);
2812 match progress {
2813 Some(InterpretationProgress::Completed(Interpretation::Complete(
2814 ItemSettlement::Rejected {
2815 item,
2816 reason: returned_reason,
2817 },
2818 ))) => {
2819 let observed = observe(&item);
2820 assert_eq!(
2821 (observed, returned_reason),
2822 (expected, reason),
2823 "replay must preserve the complete rejected request and reason"
2824 );
2825 }
2826 _ => panic!("completed ownership must survive preparation and finalization replay"),
2827 }
2828 let mut empty = (None, None);
2829 let missing = Item::interpretation_input(&mut empty);
2830 assert!(
2831 missing.is_none(),
2832 "missing input must never expose a host loan"
2833 );
2834 }
2835
2836 impl ChildInputIngress<ChildHead, u8> for User<TestAddr, u8> {
2837 fn child_input(input: u8) -> Self {
2838 User::new(TestAddr(7), input)
2839 }
2840 }
2841
2842 #[test]
2843 fn child_delivery_custody_allows_one_complete_request_and_denies_replay() {
2844 let id = CreationSequence::new()
2845 .issue()
2846 .expect("the creation ID exists");
2847 let request = ChildDelivery::<SharedProtocol, ChildHead>::after(id, 41);
2848 child_request_loan_is_affine(
2849 request,
2850 ChildDelivery::<SharedProtocol, ChildHead>::after(id, 47),
2851 ChildDeliveryReason::ClosedRecipient,
2852 |request| (request.creation, request.message),
2853 );
2854 }
2855
2856 #[test]
2857 fn private_child_input_custody_allows_one_complete_request_and_denies_replay() {
2858 let id = CreationSequence::new()
2859 .issue()
2860 .expect("the creation ID exists");
2861 let request = ChildInput::<Child, ChildHead, u8, ChildHead>::after(id, 43);
2862 child_request_loan_is_affine(
2863 request,
2864 ChildInput::<Child, ChildHead, u8, ChildHead>::after(id, 47),
2865 ChildInputReason::ClosedControlLane,
2866 |request| (request.creation, request.input),
2867 );
2868 }
2869
2870 #[test]
2871 fn creation_route_custody_allows_one_complete_batch_and_denies_replay() {
2872 let id = CreationSequence::new()
2873 .issue()
2874 .expect("the creation ID exists");
2875 let request = Creations::one(CreateChild::<TestAddr, Child>::birth(id, Child));
2876 child_request_loan_is_affine(
2877 request,
2878 Creations::one(CreateChild::<TestAddr, Child>::birth(id, Child)),
2879 ChildNamespaceExhausted,
2880 |request| {
2881 request
2882 .iter()
2883 .map(|creation| (creation.id(), creation.kind(), *creation.child()))
2884 .collect::<Vec<_>>()
2885 },
2886 );
2887 }
2888}