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, ItemSettlement, Protocol,
11 SettledItem,
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 Accepted = Creations<RoutedCreation<A, New>>;
496 type Rejection = ChildNamespaceExhausted;
497 type Prerequisite = Never;
498}
499
500pub enum EstablishedCreation<P, Occurrence>
541where
542 P: Protocol,
543 P::Addr: EndpointAddress,
544{
545 Installed {
546 id: CreationId,
547 kind: CreationKind,
548 recipient: EstablishedRecipient<P>,
549 occurrence: PhantomData<fn() -> Occurrence>,
550 },
551 Rejected {
552 id: CreationId,
553 kind: CreationKind,
554 reason: CreationRejection,
555 occurrence: PhantomData<fn() -> Occurrence>,
556 },
557}
558
559impl<P, Occurrence> EstablishedCreation<P, Occurrence>
560where
561 P: Protocol,
562 P::Addr: EndpointAddress,
563{
564 #[must_use]
565 pub const fn installed(
566 id: CreationId,
567 kind: CreationKind,
568 recipient: EstablishedRecipient<P>,
569 ) -> Self {
570 Self::Installed {
571 id,
572 kind,
573 recipient,
574 occurrence: PhantomData,
575 }
576 }
577
578 #[must_use]
579 pub const fn rejected(id: CreationId, kind: CreationKind, reason: CreationRejection) -> Self {
580 Self::Rejected {
581 id,
582 kind,
583 reason,
584 occurrence: PhantomData,
585 }
586 }
587
588 #[must_use]
589 pub const fn id(&self) -> CreationId {
590 match self {
591 Self::Installed { id, .. } | Self::Rejected { id, .. } => *id,
592 }
593 }
594
595 #[must_use]
596 pub const fn kind(&self) -> CreationKind {
597 match self {
598 Self::Installed { kind, .. } | Self::Rejected { kind, .. } => *kind,
599 }
600 }
601
602 pub fn into_recipient(self) -> Result<EstablishedRecipient<P>, CreationRejection> {
608 match self {
609 Self::Installed { recipient, .. } => Ok(recipient),
610 Self::Rejected { reason, .. } => Err(reason),
611 }
612 }
613
614 pub fn into_actor<Parent>(
626 self,
627 ) -> Result<EstablishedActor<RoleChild<Parent, Occurrence>>, CreationRejection>
628 where
629 Parent: Behavior,
630 Occurrence: ChildRole<Parent>,
631 RoleChild<Parent, Occurrence>: Behavior<Protocol = P>,
632 {
633 self.into_recipient().map(EstablishedActor::from_recipient)
634 }
635}
636
637pub enum ChildCreationOutcome<C, Occurrence>
647where
648 C: Behavior,
649 BehaviorAddr<C>: EndpointAddress,
650{
651 Established {
653 established: EstablishedCreation<C::Protocol, Occurrence>,
655 },
656 InitializationRejected {
658 creation: RoutedCreation<BehaviorAddr<C>, C>,
660 error: C::Error,
662 },
663 InitializationPanicked {
668 creation: RoutedCreation<BehaviorAddr<C>, C>,
670 },
671 HostRejected {
673 creation: RoutedCreation<BehaviorAddr<C>, C>,
675 initialization: Actions<BehaviorAddr<C>, C::Ph, C::Sends, C::Birth>,
677 reason: CreationRejection,
679 },
680}
681
682impl<C, Occurrence> ChildCreationOutcome<C, Occurrence>
683where
684 C: Behavior,
685 BehaviorAddr<C>: EndpointAddress,
686{
687 pub fn into_actor(self) -> Result<EstablishedActor<C>, Self> {
699 match self {
700 Self::Established {
701 established: EstablishedCreation::Installed { recipient, .. },
702 } => Ok(EstablishedActor::from_recipient(recipient)),
703 other => Err(other),
704 }
705 }
706}
707
708#[must_use = "a child-creation settlement must be admitted or retained"]
716pub struct ChildCreationSettled<C, Occurrence>
717where
718 C: Behavior,
719 BehaviorAddr<C>: EndpointAddress,
720{
721 settlement: SettledItem<
722 RoutedCreation<BehaviorAddr<C>, C>,
723 ItemSettlement<
724 RoutedCreation<BehaviorAddr<C>, C>,
725 ChildCreationOutcome<C, Occurrence>,
726 CreationRejection,
727 Never,
728 >,
729 >,
730}
731
732impl<C, Occurrence> ChildCreationSettled<C, Occurrence>
733where
734 C: Behavior,
735 BehaviorAddr<C>: EndpointAddress,
736{
737 #[must_use]
738 pub const fn new(
739 settlement: SettledItem<
740 RoutedCreation<BehaviorAddr<C>, C>,
741 ItemSettlement<
742 RoutedCreation<BehaviorAddr<C>, C>,
743 ChildCreationOutcome<C, Occurrence>,
744 CreationRejection,
745 Never,
746 >,
747 >,
748 ) -> Self {
749 Self { settlement }
750 }
751
752 #[must_use]
754 pub fn into_settlement(
755 self,
756 ) -> SettledItem<
757 RoutedCreation<BehaviorAddr<C>, C>,
758 ItemSettlement<
759 RoutedCreation<BehaviorAddr<C>, C>,
760 ChildCreationOutcome<C, Occurrence>,
761 CreationRejection,
762 Never,
763 >,
764 > {
765 self.settlement
766 }
767}
768
769impl<C, Occurrence> core::fmt::Debug for ChildCreationSettled<C, Occurrence>
770where
771 C: Behavior,
772 BehaviorAddr<C>: EndpointAddress,
773{
774 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
775 formatter
776 .debug_struct("ChildCreationSettled")
777 .finish_non_exhaustive()
778 }
779}
780
781pub struct CreationCorrelation<P, Occurrence>
804where
805 P: Protocol,
806{
807 id: CreationId,
808 occurrence: PhantomData<fn() -> (P, Occurrence)>,
809}
810
811impl<P, Occurrence> CreationCorrelation<P, Occurrence>
812where
813 P: Protocol,
814{
815 #[must_use]
816 pub const fn new(id: CreationId) -> Self {
817 Self {
818 id,
819 occurrence: PhantomData,
820 }
821 }
822
823 #[must_use]
824 pub const fn id(self) -> CreationId {
825 self.id
826 }
827}
828
829impl<P, Occurrence> Copy for CreationCorrelation<P, Occurrence> where P: Protocol {}
830
831impl<P, Occurrence> Clone for CreationCorrelation<P, Occurrence>
832where
833 P: Protocol,
834{
835 fn clone(&self) -> Self {
836 *self
837 }
838}
839
840impl<P, Occurrence> core::fmt::Debug for CreationCorrelation<P, Occurrence>
841where
842 P: Protocol,
843{
844 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
845 formatter
846 .debug_tuple("CreationCorrelation")
847 .field(&self.id)
848 .finish()
849 }
850}
851
852impl<P, Occurrence> PartialEq for CreationCorrelation<P, Occurrence>
853where
854 P: Protocol,
855{
856 fn eq(&self, other: &Self) -> bool {
857 self.id == other.id
858 }
859}
860
861impl<P, Occurrence> Eq for CreationCorrelation<P, Occurrence> where P: Protocol {}
862
863pub struct ChildDelivery<P, Occurrence>
870where
871 P: Protocol,
872{
873 pub creation: CreationId,
874 pub message: P::Msg,
875 occurrence: PhantomData<fn() -> Occurrence>,
876}
877
878pub struct ChildInput<Child, Source, Input, Occurrence>
891where
892 Child: Behavior,
893{
894 pub creation: CreationId,
896 pub input: Input,
898 marker: PhantomData<fn() -> (Child, Source, Occurrence)>,
899}
900
901#[derive(Clone, Copy, Debug, Eq, PartialEq)]
903pub enum ChildDeliveryReason {
904 MissingBinding,
905 ClosedRecipient,
906}
907
908#[derive(Clone, Copy, Debug, Eq, PartialEq)]
910pub enum ChildInputReason {
911 MissingBinding,
912 ClosedControlLane,
913}
914
915#[derive(Debug, Clone, Copy, PartialEq, Eq)]
922pub struct ChildReport<R> {
923 pub child: CreationId,
925 pub report: R,
927}
928
929impl<R> ChildReport<R> {
930 #[must_use]
932 pub const fn new(child: CreationId, report: R) -> Self {
933 Self { child, report }
934 }
935}
936
937impl<R> From<(CreationId, crate::ReportToParent<R>)> for ChildReport<R> {
938 fn from((child, request): (CreationId, crate::ReportToParent<R>)) -> Self {
939 Self::new(child, request.into_inner())
940 }
941}
942
943impl<Child, Source, Input, Occurrence> ChildInput<Child, Source, Input, Occurrence>
944where
945 Child: Behavior,
946 Child::Event: crate::ChildInputIngress<Source, Input>,
947{
948 #[must_use]
950 pub const fn after(creation: CreationId, input: Input) -> Self {
951 Self {
952 creation,
953 input,
954 marker: PhantomData,
955 }
956 }
957}
958
959impl<Child, Source, Input, Occurrence> Clone for ChildInput<Child, Source, Input, Occurrence>
960where
961 Child: Behavior,
962 Input: Clone,
963{
964 fn clone(&self) -> Self {
965 Self {
966 creation: self.creation,
967 input: self.input.clone(),
968 marker: PhantomData,
969 }
970 }
971}
972
973impl<P, Occurrence> ChildDelivery<P, Occurrence>
974where
975 P: Protocol,
976{
977 #[must_use]
978 pub const fn after(creation: CreationId, message: P::Msg) -> Self {
979 Self {
980 creation,
981 message,
982 occurrence: PhantomData,
983 }
984 }
985}
986
987impl<P, Occurrence> Clone for ChildDelivery<P, Occurrence>
988where
989 P: Protocol,
990 P::Msg: Clone,
991{
992 fn clone(&self) -> Self {
993 Self {
994 creation: self.creation,
995 message: self.message.clone(),
996 occurrence: PhantomData,
997 }
998 }
999}
1000
1001impl<P, Occurrence> ActionItem for ChildDelivery<P, Occurrence>
1002where
1003 P: Protocol,
1004 P::Msg: Send,
1005{
1006 type Accepted = ();
1007 type Rejection = ChildDeliveryReason;
1008 type Prerequisite = CreationCorrelation<P, Occurrence>;
1009}
1010
1011impl<Child, Source, Input, Occurrence> ActionItem for ChildInput<Child, Source, Input, Occurrence>
1012where
1013 Child: Behavior,
1014 Input: Send,
1015{
1016 type Accepted = ();
1017 type Rejection = ChildInputReason;
1018 type Prerequisite = CreationCorrelation<Child::Protocol, Occurrence>;
1019}
1020
1021pub trait EstablishChild<Occurrence, C>
1077where
1078 C: Behavior,
1079 BehaviorAddr<C>: EndpointAddress,
1080{
1081 fn establish_child(
1083 &mut self,
1084 creation: RoutedCreation<BehaviorAddr<C>, C>,
1085 ) -> impl Future<
1086 Output = ItemSettlement<
1087 RoutedCreation<BehaviorAddr<C>, C>,
1088 ChildCreationOutcome<C, Occurrence>,
1089 CreationRejection,
1090 Never,
1091 >,
1092 > + Send;
1093}
1094
1095#[doc(hidden)]
1100pub trait ChildCreationProduct<A: Address, Occurrence>: Sized {
1101 type Result;
1102}
1103
1104pub trait DispatchBirth<A: Address, Host>: ChildCreationProduct<A, ChildHead> + Sized {
1113 fn dispatch_birth(
1116 self,
1117 id: CreationId,
1118 route: A::Nonce,
1119 kind: CreationKind,
1120 host: &mut Host,
1121 ) -> impl Future<
1122 Output = ItemSettlement<
1123 RoutedCreation<A, Self>,
1124 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1125 CreationRejection,
1126 Never,
1127 >,
1128 > + Send;
1129}
1130
1131trait CreateSelectedChild<A: Address, Occurrence, Host>:
1132 ChildCreationProduct<A, Occurrence> + Sized
1133{
1134 fn dispatch_birth_at(
1135 self,
1136 id: CreationId,
1137 route: A::Nonce,
1138 kind: CreationKind,
1139 host: &mut Host,
1140 ) -> impl Future<
1141 Output = ItemSettlement<
1142 RoutedCreation<A, Self>,
1143 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1144 CreationRejection,
1145 Never,
1146 >,
1147 > + Send;
1148}
1149
1150impl<A, Child, Host> DispatchBirth<A, Host> for Child
1151where
1152 A: Address,
1153 Child: CreateSelectedChild<A, ChildHead, Host>,
1154{
1155 fn dispatch_birth(
1156 self,
1157 id: CreationId,
1158 route: A::Nonce,
1159 kind: CreationKind,
1160 host: &mut Host,
1161 ) -> impl Future<
1162 Output = ItemSettlement<
1163 RoutedCreation<A, Self>,
1164 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1165 CreationRejection,
1166 Never,
1167 >,
1168 > + Send {
1169 self.dispatch_birth_at(id, route, kind, host)
1170 }
1171}
1172
1173#[derive(Debug, Clone, PartialEq, Eq)]
1247pub enum ChildChoice<Head, Tail> {
1248 Head(Head),
1250 Tail(Tail),
1252}
1253
1254#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1256pub struct ChildHead;
1257
1258#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1260pub struct ChildTail<Position>(PhantomData<fn() -> Position>);
1261
1262pub trait ChildPosition<Children, Child: Behavior>: sealed::ChildPosition {}
1315
1316impl sealed::ChildPosition for ChildHead {}
1317
1318impl<Child: Behavior> ChildPosition<Child, Child> for ChildHead {}
1319
1320impl<Head: Behavior, Tail> ChildPosition<ChildChoice<Head, Tail>, Head> for ChildHead {}
1321
1322impl<Position> sealed::ChildPosition for ChildTail<Position> {}
1323
1324impl<Head, Tail, Position, Child> ChildPosition<ChildChoice<Head, Tail>, Child>
1325 for ChildTail<Position>
1326where
1327 Child: Behavior,
1328 Position: ChildPosition<Tail, Child>,
1329{
1330}
1331
1332pub trait BirthNodeAppend<Tail>: sealed::BirthNode + Sized
1354where
1355 Tail: sealed::BirthNode,
1356{
1357 type Output: sealed::BirthNode;
1360
1361 fn append_prefix(self) -> Self::Output;
1364
1365 fn append_tail(tail: Tail) -> Self::Output;
1367
1368 #[must_use]
1370 fn append_creations<A: Address>(
1371 prefix: Creations<CreateChild<A, Self>>,
1372 tail: Creations<CreateChild<A, Tail>>,
1373 ) -> Creations<CreateChild<A, Self::Output>> {
1374 let mut combined = Vec::with_capacity(prefix.len() + tail.len());
1375 combined.extend(prefix.into_iter().map(|creation| {
1376 let (id, child, kind) = creation.into_parts();
1377 CreateChild::from_parts(id, Self::append_prefix(child), kind)
1378 }));
1379 combined.extend(tail.into_iter().map(|creation| {
1380 let (id, child, kind) = creation.into_parts();
1381 CreateChild::from_parts(id, Self::append_tail(child), kind)
1382 }));
1383 Creations::from_items(combined)
1384 }
1385}
1386
1387impl<Tail> BirthNodeAppend<Tail> for Never
1388where
1389 Tail: sealed::BirthNode,
1390{
1391 type Output = Tail;
1392
1393 fn append_prefix(self) -> Self::Output {
1394 match self {}
1395 }
1396
1397 fn append_tail(tail: Tail) -> Self::Output {
1398 tail
1399 }
1400}
1401
1402impl<Node> BirthNodeAppend<Never> for Node
1403where
1404 Node: sealed::NonEmptyBirthNode,
1405{
1406 type Output = Node;
1407
1408 fn append_prefix(self) -> Self::Output {
1409 self
1410 }
1411
1412 fn append_tail(tail: Never) -> Self::Output {
1413 match tail {}
1414 }
1415}
1416
1417impl<Child, Tail> BirthNodeAppend<Tail> for Child
1418where
1419 Child: Behavior,
1420 Tail: sealed::NonEmptyBirthNode,
1421{
1422 type Output = ChildChoice<Child, Tail>;
1423
1424 fn append_prefix(self) -> Self::Output {
1425 ChildChoice::Head(self)
1426 }
1427
1428 fn append_tail(tail: Tail) -> Self::Output {
1429 ChildChoice::Tail(tail)
1430 }
1431}
1432
1433impl<Head, Rest, Tail> BirthNodeAppend<Tail> for ChildChoice<Head, Rest>
1434where
1435 Head: Behavior,
1436 Rest: sealed::BirthNode + BirthNodeAppend<Tail>,
1437 Tail: sealed::NonEmptyBirthNode,
1438 Rest::Output: sealed::BirthNode,
1439{
1440 type Output = ChildChoice<Head, Rest::Output>;
1441
1442 fn append_prefix(self) -> Self::Output {
1443 match self {
1444 ChildChoice::Head(head) => ChildChoice::Head(head),
1445 ChildChoice::Tail(rest) => ChildChoice::Tail(rest.append_prefix()),
1446 }
1447 }
1448
1449 fn append_tail(tail: Tail) -> Self::Output {
1450 ChildChoice::Tail(Rest::append_tail(tail))
1451 }
1452}
1453
1454impl<Parent: Behavior> ChildOccurrence<Parent> for ChildHead {
1455 type Resolution = StructuralChildOccurrence<Self>;
1456}
1457
1458impl<Parent: Behavior, Position> ChildOccurrence<Parent> for ChildTail<Position> {
1459 type Resolution = StructuralChildOccurrence<Self>;
1460}
1461
1462#[doc(hidden)]
1469pub trait ChildOccurrenceResolution<Parent: Behavior, Occurrence>:
1470 sealed::ChildOccurrenceDescriptor + sealed::OccurrenceResolution<Parent, Occurrence>
1471{
1472}
1473
1474impl<Parent, Occurrence> ChildOccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1475where
1476 Parent: Behavior,
1477 Occurrence: ChildRole<Parent>,
1478{
1479}
1480
1481impl<Parent: Behavior> ChildOccurrenceResolution<Parent, ChildHead>
1482 for StructuralChildOccurrence<ChildHead>
1483{
1484}
1485
1486impl<Parent: Behavior, Position> ChildOccurrenceResolution<Parent, ChildTail<Position>>
1487 for StructuralChildOccurrence<ChildTail<Position>>
1488{
1489}
1490
1491#[doc(hidden)]
1493pub trait ResolveChildOccurrenceDescriptor<Emitter: Behavior, Occurrence>:
1494 sealed::ChildOccurrenceDescriptor + sealed::ResolveDescriptor<Emitter, Occurrence>
1495{
1496 type Child: Behavior;
1497 type Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Self::Child>;
1498}
1499
1500impl<Emitter, Occurrence, Position> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1501 for StructuralChildOccurrence<Position>
1502where
1503 Emitter: Behavior,
1504 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1505 Position: ChildPosition<
1506 <Emitter::Birth as BirthMode>::Child,
1507 <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child,
1508 >,
1509{
1510 type Child = <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child;
1511 type Position = Position;
1512}
1513
1514impl<Emitter, Occurrence> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1515 for DeclaredChildOccurrence
1516where
1517 Emitter:
1518 Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol> + BehaviorBase,
1519 Emitter::Base: Behavior,
1520 Occurrence: ChildRole<Emitter::Base>,
1521 <Emitter::Birth as BirthMode>::Child:
1522 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1523 Occurrence::Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1524{
1525 type Child = Occurrence::Child;
1526 type Position = Occurrence::Position;
1527}
1528
1529#[doc(hidden)]
1531pub trait BirthNodeAt<Position>: sealed::BirthNode {
1532 type Child: Behavior;
1533}
1534
1535impl<Child: Behavior> BirthNodeAt<ChildHead> for Child {
1536 type Child = Child;
1537}
1538
1539impl<Head: Behavior, Tail> BirthNodeAt<ChildHead> for ChildChoice<Head, Tail>
1540where
1541 Tail: sealed::BirthNode,
1542{
1543 type Child = Head;
1544}
1545
1546impl<Head, Tail, Position> BirthNodeAt<ChildTail<Position>> for ChildChoice<Head, Tail>
1547where
1548 Head: Behavior,
1549 Tail: BirthNodeAt<Position>,
1550{
1551 type Child = <Tail as BirthNodeAt<Position>>::Child;
1552}
1553
1554pub trait ChildOccurrenceShape {
1581 type Empty;
1583
1584 type Member<Occurrence, Child: Behavior, Tail>;
1586}
1587
1588pub trait ChildOccurrenceProduct<Shape>: sealed::BirthNode
1615where
1616 Shape: ChildOccurrenceShape,
1617{
1618 type Product;
1620}
1621
1622#[doc(hidden)]
1625pub trait ChildOccurrenceProductAt<Occurrence, Shape>: sealed::BirthNode
1626where
1627 Shape: ChildOccurrenceShape,
1628{
1629 type Product;
1630}
1631
1632impl<Node, Shape> ChildOccurrenceProduct<Shape> for Node
1633where
1634 Node: ChildOccurrenceProductAt<ChildHead, Shape>,
1635 Shape: ChildOccurrenceShape,
1636{
1637 type Product = <Node as ChildOccurrenceProductAt<ChildHead, Shape>>::Product;
1638}
1639
1640impl<Occurrence, Shape, Child> ChildOccurrenceProductAt<Occurrence, Shape> for Child
1641where
1642 Shape: ChildOccurrenceShape,
1643 Child: Behavior,
1644{
1645 type Product = Shape::Member<Occurrence, Child, Shape::Empty>;
1646}
1647
1648impl<Occurrence, Shape, Head, Tail> ChildOccurrenceProductAt<Occurrence, Shape>
1649 for ChildChoice<Head, Tail>
1650where
1651 Shape: ChildOccurrenceShape,
1652 Head: Behavior,
1653 Tail: ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>,
1654{
1655 type Product = Shape::Member<
1656 Occurrence,
1657 Head,
1658 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1659 >;
1660}
1661
1662impl<Occurrence, Shape> ChildOccurrenceProductAt<Occurrence, Shape> for Never
1663where
1664 Shape: ChildOccurrenceShape,
1665{
1666 type Product = Shape::Empty;
1667}
1668
1669pub type ChildOccurrences<Node, Shape> = <Node as ChildOccurrenceProduct<Shape>>::Product;
1671
1672mod sealed {
1673 use super::{
1674 Behavior, BehaviorBase, BirthMode, BirthNodeAt, ChildChoice, ChildHead, ChildOccurrence,
1675 ChildRole, ChildTail, DeclaredChildOccurrence, Never, ResolveChildOccurrenceDescriptor,
1676 StructuralChildOccurrence,
1677 };
1678
1679 pub trait BirthNode {}
1680
1681 pub trait NonEmptyBirthNode: BirthNode {}
1682
1683 impl<Child: Behavior> BirthNode for Child {}
1684 impl<Child: Behavior> NonEmptyBirthNode for Child {}
1685
1686 impl<Head, Tail> BirthNode for ChildChoice<Head, Tail>
1687 where
1688 Head: Behavior,
1689 Tail: BirthNode,
1690 {
1691 }
1692
1693 impl<Head, Tail> NonEmptyBirthNode for ChildChoice<Head, Tail>
1694 where
1695 Head: Behavior,
1696 Tail: BirthNode,
1697 {
1698 }
1699
1700 impl BirthNode for Never {}
1701
1702 pub trait ChildPosition {}
1703 pub trait ChildProduct {}
1704
1705 pub trait ChildOccurrenceDescriptor {}
1706
1707 impl ChildOccurrenceDescriptor for DeclaredChildOccurrence {}
1708
1709 impl<Position> ChildOccurrenceDescriptor for StructuralChildOccurrence<Position> {}
1710
1711 pub trait OccurrenceResolution<Parent: Behavior, Occurrence> {}
1712
1713 impl<Parent, Occurrence> OccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1714 where
1715 Parent: Behavior,
1716 Occurrence: ChildRole<Parent>,
1717 {
1718 }
1719
1720 impl<Parent: Behavior> OccurrenceResolution<Parent, ChildHead>
1721 for StructuralChildOccurrence<ChildHead>
1722 {
1723 }
1724
1725 impl<Parent: Behavior, Position> OccurrenceResolution<Parent, ChildTail<Position>>
1726 for StructuralChildOccurrence<ChildTail<Position>>
1727 {
1728 }
1729
1730 pub trait ResolveDescriptor<Emitter: Behavior, Occurrence> {}
1731
1732 impl<Emitter, Occurrence, Position> ResolveDescriptor<Emitter, Occurrence>
1733 for StructuralChildOccurrence<Position>
1734 where
1735 Emitter: Behavior,
1736 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1737 {
1738 }
1739
1740 impl<Emitter, Occurrence> ResolveDescriptor<Emitter, Occurrence> for DeclaredChildOccurrence
1741 where
1742 Emitter: Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol>
1743 + BehaviorBase,
1744 Emitter::Base: Behavior,
1745 Occurrence: ChildRole<Emitter::Base>,
1746 <Emitter::Birth as BirthMode>::Child:
1747 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1748 Occurrence::Position:
1749 super::ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1750 {
1751 }
1752
1753 pub trait ResolveChildOccurrence<Occurrence> {}
1754
1755 impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
1756 where
1757 Emitter: Behavior + BehaviorBase,
1758 Emitter::Base: Behavior,
1759 Occurrence: ChildOccurrence<Emitter::Base>,
1760 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
1761 {
1762 }
1763}
1764
1765#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1767pub struct NoChildren;
1768
1769impl sealed::ChildProduct for NoChildren {}
1770
1771pub struct ChildCons<A: Address, C, Earlier> {
1773 creation: CreateChild<A, C>,
1774 earlier: Earlier,
1775}
1776
1777impl<A: Address, C, Earlier> sealed::ChildProduct for ChildCons<A, C, Earlier> {}
1778
1779pub struct Children<A: Address, Product = NoChildren> {
1785 product: Product,
1786 address: PhantomData<fn() -> A>,
1787}
1788
1789pub trait ChildProduct<A: Address>: sealed::ChildProduct + Sized {
1791 type Choice: BirthNodeAppend<Never>;
1793
1794 #[doc(hidden)]
1795 fn stage(self) -> Vec<CreateChild<A, Self::Choice>>;
1796}
1797
1798impl<A: Address> ChildProduct<A> for NoChildren {
1799 type Choice = Never;
1800
1801 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1802 Vec::new()
1803 }
1804}
1805
1806impl<A, C, Earlier> ChildProduct<A> for ChildCons<A, C, Earlier>
1807where
1808 A: Address,
1809 C: Behavior,
1810 C::Protocol: Protocol<Addr = A>,
1811 Earlier: ChildProduct<A>,
1812{
1813 type Choice = ChildChoice<C, Earlier::Choice>;
1814
1815 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1816 let earlier = self.earlier.stage();
1817 let mut creates = earlier
1818 .into_iter()
1819 .map(|creation| {
1820 let (id, child, kind) = creation.into_parts();
1821 CreateChild::from_parts(id, ChildChoice::Tail(child), kind)
1822 })
1823 .collect::<Vec<_>>();
1824 let (id, child, kind) = self.creation.into_parts();
1825 creates.push(CreateChild::from_parts(id, ChildChoice::Head(child), kind));
1826 creates
1827 }
1828}
1829
1830impl<A: Address> Children<A, NoChildren> {
1831 #[must_use]
1833 pub const fn new() -> Self {
1834 Self {
1835 product: NoChildren,
1836 address: PhantomData,
1837 }
1838 }
1839}
1840
1841impl<A: Address> Default for Children<A, NoChildren> {
1842 fn default() -> Self {
1843 Self::new()
1844 }
1845}
1846
1847impl<A: Address, Product> Children<A, Product> {
1848 #[must_use]
1850 pub fn create<C>(self, creation: CreateChild<A, C>) -> Children<A, ChildCons<A, C, Product>>
1851 where
1852 C: Behavior,
1853 C::Protocol: Protocol<Addr = A>,
1854 {
1855 Children {
1856 product: ChildCons {
1857 creation,
1858 earlier: self.product,
1859 },
1860 address: PhantomData,
1861 }
1862 }
1863
1864 #[must_use]
1866 pub fn child<C>(self, id: CreationId, child: C) -> Children<A, ChildCons<A, C, Product>>
1867 where
1868 C: Behavior,
1869 C::Protocol: Protocol<Addr = A>,
1870 {
1871 self.create(CreateChild::birth(id, child))
1872 }
1873}
1874
1875impl<A, Product> Children<A, Product>
1876where
1877 A: Address,
1878 Product: ChildProduct<A>,
1879{
1880 #[must_use]
1882 pub fn into_creates(self) -> Creations<CreateChild<A, Product::Choice>> {
1883 Creations::from_items(self.product.stage())
1884 }
1885}
1886
1887impl<A, Occurrence, Head, Tail> ChildCreationProduct<A, Occurrence> for ChildChoice<Head, Tail>
1888where
1889 A: EndpointAddress,
1890 Head: Behavior,
1891 Head::Protocol: Protocol<Addr = A>,
1892 Tail: ChildCreationProduct<A, ChildTail<Occurrence>>,
1893{
1894 type Result = ChildChoice<
1895 ChildCreationOutcome<Head, Occurrence>,
1896 <Tail as ChildCreationProduct<A, ChildTail<Occurrence>>>::Result,
1897 >;
1898}
1899
1900impl<A, Occurrence, Head, Tail, Host> CreateSelectedChild<A, Occurrence, Host>
1901 for ChildChoice<Head, Tail>
1902where
1903 A: EndpointAddress,
1904 A::Nonce: Send,
1905 Head: Behavior + Send,
1906 Head::Protocol: Protocol<Addr = A>,
1907 Tail: CreateSelectedChild<A, ChildTail<Occurrence>, Host> + Send,
1908 Host: EstablishChild<Occurrence, Head> + Send,
1909{
1910 async fn dispatch_birth_at(
1911 self,
1912 id: CreationId,
1913 route: A::Nonce,
1914 kind: CreationKind,
1915 host: &mut Host,
1916 ) -> ItemSettlement<
1917 RoutedCreation<A, Self>,
1918 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1919 CreationRejection,
1920 Never,
1921 > {
1922 match self {
1923 Self::Head(child) => {
1924 let creation = RoutedCreation::new(CreateChild::from_parts(id, child, kind), route);
1925 match host.establish_child(creation).await {
1926 ItemSettlement::Accepted(receipt) => {
1927 ItemSettlement::Accepted(ChildChoice::Head(receipt))
1928 }
1929 ItemSettlement::Rejected { item, reason } => {
1930 let (creation, route) = item.into_parts();
1931 let (id, child, kind) = creation.into_parts();
1932 ItemSettlement::Rejected {
1933 item: RoutedCreation::new(
1934 CreateChild::from_parts(id, Self::Head(child), kind),
1935 route,
1936 ),
1937 reason,
1938 }
1939 }
1940 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
1941 ItemSettlement::Corrupt { item, fault } => {
1942 let (creation, route) = item.into_parts();
1943 let (id, child, kind) = creation.into_parts();
1944 ItemSettlement::Corrupt {
1945 item: RoutedCreation::new(
1946 CreateChild::from_parts(id, Self::Head(child), kind),
1947 route,
1948 ),
1949 fault,
1950 }
1951 }
1952 }
1953 }
1954 Self::Tail(tail) => match tail.dispatch_birth_at(id, route, kind, host).await {
1955 ItemSettlement::Accepted(receipt) => {
1956 ItemSettlement::Accepted(ChildChoice::Tail(receipt))
1957 }
1958 ItemSettlement::Rejected { item, reason } => {
1959 let (creation, route) = item.into_parts();
1960 let (id, child, kind) = creation.into_parts();
1961 ItemSettlement::Rejected {
1962 item: RoutedCreation::new(
1963 CreateChild::from_parts(id, Self::Tail(child), kind),
1964 route,
1965 ),
1966 reason,
1967 }
1968 }
1969 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
1970 ItemSettlement::Corrupt { item, fault } => {
1971 let (creation, route) = item.into_parts();
1972 let (id, child, kind) = creation.into_parts();
1973 ItemSettlement::Corrupt {
1974 item: RoutedCreation::new(
1975 CreateChild::from_parts(id, Self::Tail(child), kind),
1976 route,
1977 ),
1978 fault,
1979 }
1980 }
1981 },
1982 }
1983 }
1984}
1985
1986impl<A, Occurrence> ChildCreationProduct<A, Occurrence> for Never
1987where
1988 A: Address,
1989{
1990 type Result = Never;
1991}
1992
1993impl<A, Occurrence, Host> CreateSelectedChild<A, Occurrence, Host> for Never
1994where
1995 A: Address,
1996{
1997 fn dispatch_birth_at(
1998 self,
1999 _id: CreationId,
2000 _route: A::Nonce,
2001 _kind: CreationKind,
2002 _host: &mut Host,
2003 ) -> impl Future<
2004 Output = ItemSettlement<
2005 RoutedCreation<A, Self>,
2006 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2007 CreationRejection,
2008 Never,
2009 >,
2010 > + Send {
2011 async move { match self {} }
2012 }
2013}
2014
2015impl<A, Occurrence, C> ChildCreationProduct<A, Occurrence> for C
2016where
2017 A: EndpointAddress,
2018 C: Behavior,
2019 C::Protocol: Protocol<Addr = A>,
2020{
2021 type Result = ChildCreationOutcome<C, Occurrence>;
2022}
2023
2024impl<A, Occurrence, C, Host> CreateSelectedChild<A, Occurrence, Host> for C
2025where
2026 A: EndpointAddress,
2027 C: Behavior,
2028 C::Protocol: Protocol<Addr = A>,
2029 Host: EstablishChild<Occurrence, C>,
2030{
2031 fn dispatch_birth_at(
2032 self,
2033 id: CreationId,
2034 route: A::Nonce,
2035 kind: CreationKind,
2036 host: &mut Host,
2037 ) -> impl Future<
2038 Output = ItemSettlement<
2039 RoutedCreation<A, Self>,
2040 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2041 CreationRejection,
2042 Never,
2043 >,
2044 > + Send {
2045 host.establish_child(RoutedCreation::new(
2046 CreateChild::from_parts(id, self, kind),
2047 route,
2048 ))
2049 }
2050}
2051
2052pub trait BirthMode {
2054 type Child;
2055}
2056
2057pub struct NoBirthProtocols;
2059
2060pub struct BirthProtocol<P: Protocol, Tail> {
2062 protocol: PhantomData<fn() -> P>,
2063 tail: PhantomData<fn() -> Tail>,
2064}
2065
2066pub struct BirthProtocolHead;
2068
2069pub struct BirthProtocolTail<Position>(PhantomData<fn() -> Position>);
2071
2072pub trait BirthProtocolAt<P: Protocol, Position> {}
2074
2075impl<P: Protocol, Tail> BirthProtocolAt<P, BirthProtocolHead> for BirthProtocol<P, Tail> {}
2076
2077impl<Head, Tail, P, Position> BirthProtocolAt<P, BirthProtocolTail<Position>>
2078 for BirthProtocol<Head, Tail>
2079where
2080 Head: Protocol,
2081 P: Protocol,
2082 Tail: BirthProtocolAt<P, Position>,
2083{
2084}
2085
2086pub trait BirthProtocolProduct {
2088 type Append<Tail: BirthProtocolProduct>: BirthProtocolProduct;
2089}
2090
2091impl BirthProtocolProduct for NoBirthProtocols {
2092 type Append<Tail: BirthProtocolProduct> = Tail;
2093}
2094
2095impl<P, Rest> BirthProtocolProduct for BirthProtocol<P, Rest>
2096where
2097 P: Protocol,
2098 Rest: BirthProtocolProduct,
2099{
2100 type Append<Tail: BirthProtocolProduct> = BirthProtocol<P, Rest::Append<Tail>>;
2101}
2102
2103pub trait BirthProtocols: Behavior {
2109 type Protocols: BirthProtocolProduct;
2110}
2111
2112impl<B> BirthProtocols for B
2113where
2114 B: Behavior,
2115 B::Birth: BirthModeProtocols,
2116{
2117 type Protocols = BirthProtocol<B::Protocol, <B::Birth as BirthModeProtocols>::Protocols>;
2118}
2119
2120#[doc(hidden)]
2121pub trait BirthModeProtocols {
2122 type Protocols: BirthProtocolProduct;
2123}
2124
2125impl<M> BirthModeProtocols for M
2126where
2127 M: BirthMode,
2128 M::Child: BirthNodeProtocols,
2129{
2130 type Protocols = <M::Child as BirthNodeProtocols>::Protocols;
2131}
2132
2133#[doc(hidden)]
2134pub trait BirthNodeProtocols {
2135 type Protocols: BirthProtocolProduct;
2136}
2137
2138impl<B> BirthNodeProtocols for B
2139where
2140 B: BirthProtocols,
2141{
2142 type Protocols = B::Protocols;
2143}
2144
2145impl<Head, Tail> BirthNodeProtocols for ChildChoice<Head, Tail>
2146where
2147 Head: BirthNodeProtocols,
2148 Tail: BirthNodeProtocols,
2149{
2150 type Protocols = <Head::Protocols as BirthProtocolProduct>::Append<Tail::Protocols>;
2151}
2152
2153impl BirthNodeProtocols for Never {
2154 type Protocols = NoBirthProtocols;
2155}
2156
2157#[doc(hidden)]
2162pub trait BirthNodeLogicalHosts {
2163 type LogicalHosts: BirthProtocolProduct;
2164}
2165
2166impl<B> BirthNodeLogicalHosts for B
2167where
2168 B: crate::LogicalHostRequirements,
2169{
2170 type LogicalHosts = B::LogicalHosts;
2171}
2172
2173impl<Head, Tail> BirthNodeLogicalHosts for ChildChoice<Head, Tail>
2174where
2175 Head: BirthNodeLogicalHosts,
2176 Tail: BirthNodeLogicalHosts,
2177{
2178 type LogicalHosts = <Head::LogicalHosts as BirthProtocolProduct>::Append<Tail::LogicalHosts>;
2179}
2180
2181impl BirthNodeLogicalHosts for Never {
2182 type LogicalHosts = NoBirthProtocols;
2183}
2184
2185#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2187pub struct NoBirths;
2188
2189impl BirthMode for NoBirths {
2190 type Child = Never;
2191}
2192
2193#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2195pub struct Births<C>(PhantomData<fn() -> C>);
2196
2197impl<C> BirthMode for Births<C> {
2198 type Child = C;
2199}
2200
2201#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2209pub struct RetirementBirths<C>(PhantomData<fn() -> C>);
2210
2211impl<C> BirthMode for RetirementBirths<C> {
2212 type Child = C;
2213}
2214
2215#[cfg(test)]
2216mod tests {
2217 use super::*;
2218 use crate::{Actions, BehaviorActed, NoBirths, User};
2219
2220 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2221 struct TestAddr(u64);
2222
2223 impl Address for TestAddr {
2224 type Nonce = u64;
2225 }
2226
2227 struct TestEndpoint<P>(PhantomData<fn() -> P>);
2228
2229 impl<P> Clone for TestEndpoint<P> {
2230 fn clone(&self) -> Self {
2231 *self
2232 }
2233 }
2234
2235 impl<P> Copy for TestEndpoint<P> {}
2236
2237 impl EndpointAddress for TestAddr {
2238 type Established<P>
2239 = TestEndpoint<P>
2240 where
2241 P: Protocol<Addr = Self>;
2242 }
2243
2244 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2245 struct Child;
2246
2247 struct SharedProtocol;
2248
2249 impl behavior::Protocol for SharedProtocol {
2250 type Addr = TestAddr;
2251 type Msg = u8;
2252 }
2253
2254 struct Primary;
2255 struct Fallback;
2256
2257 macro_rules! shared_protocol_behavior {
2258 ($behavior:ty, $birth:ty) => {
2259 impl Behavior for $behavior {
2260 type Protocol = SharedProtocol;
2261 type Event = User<TestAddr, u8>;
2262 type Sends = Vec<Never>;
2263 type Ph = Never;
2264 type Error = Never;
2265 type Birth = $birth;
2266
2267 fn transition(
2268 &mut self,
2269 _: crate::ActiveTurn,
2270 _: Self::Event,
2271 ) -> BehaviorActed<Self> {
2272 Ok(Actions::cont())
2273 }
2274 }
2275 };
2276 }
2277
2278 shared_protocol_behavior!(Primary, Births<Child>);
2279 shared_protocol_behavior!(Fallback, NoBirths);
2280
2281 impl behavior::Protocol for Child {
2282 type Addr = TestAddr;
2283 type Msg = u8;
2284 }
2285
2286 impl Behavior for Child {
2287 type Protocol = Self;
2288 type Event = User<TestAddr, u8>;
2289 type Sends = Vec<Never>;
2290 type Ph = Never;
2291 type Error = Never;
2292 type Birth = NoBirths;
2293
2294 fn transition(&mut self, _: crate::ActiveTurn, _: Self::Event) -> BehaviorActed<Self> {
2295 Ok(Actions::cont())
2296 }
2297 }
2298
2299 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2300 enum ChildPlan {
2301 CreateChild,
2302 RejectBeforeTransfer,
2303 }
2304
2305 struct RecordingHost {
2306 calls: usize,
2307 observed: Vec<(CreationId, u64, CreationKind)>,
2308 plan: ChildPlan,
2309 }
2310
2311 #[derive(Debug, PartialEq, Eq)]
2312 enum SharedCreation {
2313 Primary(CreationId, u64),
2314 Fallback(CreationId, u64),
2315 }
2316
2317 #[derive(Default)]
2318 struct SharedProtocolHost(Vec<SharedCreation>);
2319
2320 impl EstablishChild<ChildHead, Primary> for SharedProtocolHost {
2321 async fn establish_child(
2322 &mut self,
2323 creation: RoutedCreation<TestAddr, Primary>,
2324 ) -> ItemSettlement<
2325 RoutedCreation<TestAddr, Primary>,
2326 ChildCreationOutcome<Primary, ChildHead>,
2327 CreationRejection,
2328 Never,
2329 > {
2330 let id = creation.id();
2331 let kind = creation.kind();
2332 let route = creation.route();
2333 let (creation, _) = creation.into_parts();
2334 let (_, _child, _) = creation.into_parts();
2335 self.0.push(SharedCreation::Primary(id, route));
2336 ItemSettlement::Accepted(ChildCreationOutcome::Established {
2337 established: EstablishedCreation::installed(
2338 id,
2339 kind,
2340 EstablishedRecipient::issued(TestEndpoint(PhantomData)),
2341 ),
2342 })
2343 }
2344 }
2345
2346 impl EstablishChild<ChildTail<ChildHead>, Fallback> for SharedProtocolHost {
2347 async fn establish_child(
2348 &mut self,
2349 creation: RoutedCreation<TestAddr, Fallback>,
2350 ) -> ItemSettlement<
2351 RoutedCreation<TestAddr, Fallback>,
2352 ChildCreationOutcome<Fallback, ChildTail<ChildHead>>,
2353 CreationRejection,
2354 Never,
2355 > {
2356 let id = creation.id();
2357 let kind = creation.kind();
2358 let route = creation.route();
2359 let (creation, _) = creation.into_parts();
2360 let (_, _child, _) = creation.into_parts();
2361 self.0.push(SharedCreation::Fallback(id, route));
2362 ItemSettlement::Accepted(ChildCreationOutcome::Established {
2363 established: EstablishedCreation::installed(
2364 id,
2365 kind,
2366 EstablishedRecipient::issued(TestEndpoint(PhantomData)),
2367 ),
2368 })
2369 }
2370 }
2371
2372 impl EstablishChild<ChildHead, Child> for RecordingHost {
2373 async fn establish_child(
2374 &mut self,
2375 creation: RoutedCreation<TestAddr, Child>,
2376 ) -> ItemSettlement<
2377 RoutedCreation<TestAddr, Child>,
2378 ChildCreationOutcome<Child, ChildHead>,
2379 CreationRejection,
2380 Never,
2381 > {
2382 self.calls += 1;
2383 self.observed
2384 .push((creation.id(), creation.route(), creation.kind()));
2385 match self.plan {
2386 ChildPlan::CreateChild => {
2387 let id = creation.id();
2388 let kind = creation.kind();
2389 let (creation, _) = creation.into_parts();
2390 let (_, _child, _) = creation.into_parts();
2391 ItemSettlement::Accepted(ChildCreationOutcome::Established {
2392 established: EstablishedCreation::installed(
2393 id,
2394 kind,
2395 EstablishedRecipient::issued(TestEndpoint(PhantomData)),
2396 ),
2397 })
2398 }
2399 ChildPlan::RejectBeforeTransfer => ItemSettlement::Rejected {
2400 item: creation,
2401 reason: CreationRejection::EnvironmentFailed,
2402 },
2403 }
2404 }
2405 }
2406
2407 fn host(plan: ChildPlan) -> RecordingHost {
2408 RecordingHost {
2409 calls: 0,
2410 observed: Vec::new(),
2411 plan,
2412 }
2413 }
2414
2415 fn assert_send<T: Send>(_: &T) {}
2416
2417 #[test]
2418 fn empty_child_product_stages_no_creations() {
2419 let creations = <NoChildren as ChildProduct<TestAddr>>::stage(NoChildren);
2420 assert!(creations.is_empty());
2421 }
2422
2423 #[test]
2424 fn creation_values_preserve_ids_order_and_debug_identity() {
2425 let mut sequence = CreationSequence::new();
2426 let first = sequence.issue().expect("the first creation ID exists");
2427 let second = sequence.issue().expect("the second creation ID exists");
2428 assert_eq!(first.get(), 1);
2429 assert_eq!(second.get(), 2);
2430
2431 let first_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2432 let same_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2433 let second_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(second);
2434 assert_eq!(first_correlation, same_correlation);
2435 assert_ne!(first_correlation, second_correlation);
2436 assert_eq!(
2437 format!("{first_correlation:?}"),
2438 "CreationCorrelation(CreationId(1))"
2439 );
2440
2441 let mut creations = Creations::one(1_u8);
2442 creations.extend([2, 3]);
2443 assert_eq!(creations.len(), 3);
2444 assert!(!creations.is_empty());
2445 assert_eq!(creations.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
2446 let borrowed = (&creations).into_iter().copied().collect::<Vec<_>>();
2447 assert_eq!(borrowed, [1, 2, 3]);
2448
2449 let collected: Creations<_> = [4_u8, 5].into_iter().collect();
2450 assert_eq!(collected.len(), 2);
2451 let collected_values = collected.into_iter().collect::<Vec<_>>();
2452 assert_eq!(collected_values, [4, 5]);
2453
2454 let returned = ChildCreationSettled::<Child, ChildHead>::new(SettledItem::Unattempted(
2455 RoutedCreation::new(CreateChild::birth(first, Child), 17),
2456 ));
2457 assert_eq!(format!("{returned:?}"), "ChildCreationSettled { .. }");
2458 }
2459
2460 #[tokio::test]
2461 async fn concrete_child_dispatches_once_with_exact_creation_and_route() {
2462 let mut sequence = CreationSequence::new();
2463 let previous = sequence.issue().expect("the previous ID exists");
2464 let id = sequence.issue().expect("the replacement ID exists");
2465 let mut host = host(ChildPlan::CreateChild);
2466 let kind = CreationKind::replacement(previous);
2467 let future = Child.dispatch_birth(id, 17, kind, &mut host);
2468 assert_send(&future);
2469 let result = future.await;
2470
2471 let ItemSettlement::Accepted(ChildCreationOutcome::Established { established }) = result
2472 else {
2473 panic!("expected the child to be created");
2474 };
2475 assert_eq!(established.id(), id);
2476 assert_eq!(host.calls, 1);
2477 assert_eq!(host.observed, [(id, 17, kind)]);
2478 }
2479
2480 #[tokio::test]
2481 async fn concrete_child_returns_the_exact_rejected_creation_without_retry() {
2482 let mut sequence = CreationSequence::new();
2483 let previous = sequence.issue().expect("the previous ID exists");
2484 let id = sequence.issue().expect("the replacement ID exists");
2485 let mut host = host(ChildPlan::RejectBeforeTransfer);
2486 let kind = CreationKind::replacement(previous);
2487 let future = Child.dispatch_birth(id, 23, kind, &mut host);
2488 assert_send(&future);
2489 let result = future.await;
2490
2491 let ItemSettlement::Rejected { item, reason } = result else {
2492 panic!("expected refusal before child ownership transfer");
2493 };
2494 assert_eq!(
2495 item,
2496 RoutedCreation::new(CreateChild::replacement(id, previous, Child), 23)
2497 );
2498 assert_eq!(reason, CreationRejection::EnvironmentFailed);
2499 assert_eq!(host.calls, 1);
2500 assert_eq!(host.observed, [(id, 23, kind)]);
2501 }
2502
2503 #[tokio::test]
2504 async fn distinct_child_alternatives_preserve_one_canonical_protocol_identity() {
2505 type Alternatives = ChildChoice<Primary, ChildChoice<Fallback, Never>>;
2506
2507 fn requires_shared_protocol<C: Behavior<Protocol = SharedProtocol>>() {}
2508 requires_shared_protocol::<Primary>();
2509 requires_shared_protocol::<Fallback>();
2510
2511 let mut sequence = CreationSequence::new();
2512 let primary_id = sequence.issue().expect("the primary ID exists");
2513 let fallback_id = sequence.issue().expect("the fallback ID exists");
2514 let mut host = SharedProtocolHost::default();
2515 let primary = Alternatives::Head(Primary)
2516 .dispatch_birth(primary_id, 11, CreationKind::Birth, &mut host)
2517 .await;
2518 let fallback = Alternatives::Tail(ChildChoice::Head(Fallback))
2519 .dispatch_birth(fallback_id, 17, CreationKind::Birth, &mut host)
2520 .await;
2521
2522 let ItemSettlement::Accepted(ChildChoice::Head(ChildCreationOutcome::Established {
2523 established: primary,
2524 })) = primary
2525 else {
2526 panic!("expected the primary child result");
2527 };
2528 assert_eq!(primary.id(), primary_id);
2529 let ItemSettlement::Accepted(ChildChoice::Tail(ChildChoice::Head(
2530 ChildCreationOutcome::Established {
2531 established: fallback,
2532 },
2533 ))) = fallback
2534 else {
2535 panic!("expected the fallback child result");
2536 };
2537 assert_eq!(fallback.id(), fallback_id);
2538
2539 assert_eq!(
2540 host.0,
2541 [
2542 SharedCreation::Primary(primary_id, 11),
2543 SharedCreation::Fallback(fallback_id, 17),
2544 ]
2545 );
2546 }
2547
2548 #[test]
2549 fn birth_protocol_projection_recurses_without_inspecting_send_lanes() {
2550 type Protocols = <Primary as BirthProtocols>::Protocols;
2551 type Expected = BirthProtocol<SharedProtocol, BirthProtocol<Child, NoBirthProtocols>>;
2552
2553 trait Same<T> {}
2554 impl<T> Same<T> for T {}
2555 fn exact<T: Same<Expected>>() {}
2556 exact::<Protocols>();
2557 }
2558}