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 struct CommittedChild<C, Occurrence>
504where
505 C: Behavior,
506 BehaviorAddr<C>: EndpointAddress,
507{
508 id: CreationId,
509 kind: CreationKind,
510 actor: EstablishedActor<C>,
511 occurrence: PhantomData<fn() -> Occurrence>,
512}
513
514impl<C, Occurrence> CommittedChild<C, Occurrence>
515where
516 C: Behavior,
517 BehaviorAddr<C>: EndpointAddress,
518{
519 #[must_use]
523 pub const fn new(id: CreationId, kind: CreationKind, actor: EstablishedActor<C>) -> Self {
524 Self {
525 id,
526 kind,
527 actor,
528 occurrence: PhantomData,
529 }
530 }
531
532 #[must_use]
533 pub const fn id(&self) -> CreationId {
534 self.id
535 }
536
537 #[must_use]
538 pub const fn kind(&self) -> CreationKind {
539 self.kind
540 }
541
542 #[must_use]
543 pub fn actor(&self) -> EstablishedActor<C> {
544 self.actor.clone()
545 }
546
547 #[must_use]
548 pub fn into_parts(self) -> (CreationId, CreationKind, EstablishedActor<C>) {
549 (self.id, self.kind, self.actor)
550 }
551}
552
553pub enum EstablishedCreation<C, Occurrence>
592where
593 C: Behavior,
594 BehaviorAddr<C>: EndpointAddress,
595{
596 Installed(CommittedChild<C, Occurrence>),
597 Rejected {
598 id: CreationId,
599 kind: CreationKind,
600 reason: CreationRejection,
601 occurrence: PhantomData<fn() -> Occurrence>,
602 },
603}
604
605impl<C, Occurrence> EstablishedCreation<C, Occurrence>
606where
607 C: Behavior,
608 BehaviorAddr<C>: EndpointAddress,
609{
610 #[must_use]
611 pub const fn installed(child: CommittedChild<C, Occurrence>) -> Self {
612 Self::Installed(child)
613 }
614
615 #[must_use]
616 pub const fn rejected(id: CreationId, kind: CreationKind, reason: CreationRejection) -> Self {
617 Self::Rejected {
618 id,
619 kind,
620 reason,
621 occurrence: PhantomData,
622 }
623 }
624
625 #[must_use]
626 pub const fn id(&self) -> CreationId {
627 match self {
628 Self::Installed(child) => child.id(),
629 Self::Rejected { id, .. } => *id,
630 }
631 }
632
633 #[must_use]
634 pub const fn kind(&self) -> CreationKind {
635 match self {
636 Self::Installed(child) => child.kind(),
637 Self::Rejected { kind, .. } => *kind,
638 }
639 }
640
641 pub fn into_recipient(self) -> Result<EstablishedRecipient<C::Protocol>, CreationRejection> {
647 match self {
648 Self::Installed(child) => Ok(child.into_parts().2.into_recipient()),
649 Self::Rejected { reason, .. } => Err(reason),
650 }
651 }
652
653 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, CreationRejection> {
660 match self {
661 Self::Installed(child) => Ok(child),
662 Self::Rejected { reason, .. } => Err(reason),
663 }
664 }
665}
666
667pub enum ChildCreationOutcome<C, Occurrence>
691where
692 C: Behavior,
693 BehaviorAddr<C>: EndpointAddress,
694{
695 Established(CommittedChild<C, Occurrence>),
697 InitializationRejected {
699 creation: RoutedCreation<BehaviorAddr<C>, C>,
701 error: C::Error,
703 },
704 InitializationPanicked {
709 creation: RoutedCreation<BehaviorAddr<C>, C>,
711 },
712 HostRejected {
714 creation: RoutedCreation<BehaviorAddr<C>, C>,
716 initialization: Actions<BehaviorAddr<C>, C::Ph, C::Sends, C::Birth>,
718 reason: CreationRejection,
720 },
721}
722
723impl<C, Occurrence> ChildCreationOutcome<C, Occurrence>
724where
725 C: Behavior,
726 BehaviorAddr<C>: EndpointAddress,
727{
728 pub fn into_committed(self) -> Result<CommittedChild<C, Occurrence>, Self> {
738 match self {
739 Self::Established(child) => Ok(child),
740 other => Err(other),
741 }
742 }
743
744 pub fn into_actor(self) -> Result<EstablishedActor<C>, Self> {
749 self.into_committed().map(|child| child.into_parts().2)
750 }
751}
752
753#[must_use = "a child-creation settlement must be admitted or retained"]
761pub struct ChildCreationSettled<C, Occurrence>
762where
763 C: Behavior,
764 BehaviorAddr<C>: EndpointAddress,
765{
766 settlement: SettledItem<
767 RoutedCreation<BehaviorAddr<C>, C>,
768 ItemSettlement<
769 RoutedCreation<BehaviorAddr<C>, C>,
770 ChildCreationOutcome<C, Occurrence>,
771 CreationRejection,
772 Never,
773 >,
774 >,
775}
776
777impl<C, Occurrence> ChildCreationSettled<C, Occurrence>
778where
779 C: Behavior,
780 BehaviorAddr<C>: EndpointAddress,
781{
782 #[must_use]
783 pub const fn new(
784 settlement: SettledItem<
785 RoutedCreation<BehaviorAddr<C>, C>,
786 ItemSettlement<
787 RoutedCreation<BehaviorAddr<C>, C>,
788 ChildCreationOutcome<C, Occurrence>,
789 CreationRejection,
790 Never,
791 >,
792 >,
793 ) -> Self {
794 Self { settlement }
795 }
796
797 #[must_use]
799 pub fn into_settlement(
800 self,
801 ) -> SettledItem<
802 RoutedCreation<BehaviorAddr<C>, C>,
803 ItemSettlement<
804 RoutedCreation<BehaviorAddr<C>, C>,
805 ChildCreationOutcome<C, Occurrence>,
806 CreationRejection,
807 Never,
808 >,
809 > {
810 self.settlement
811 }
812}
813
814impl<C, Occurrence> core::fmt::Debug for ChildCreationSettled<C, Occurrence>
815where
816 C: Behavior,
817 BehaviorAddr<C>: EndpointAddress,
818{
819 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
820 formatter
821 .debug_struct("ChildCreationSettled")
822 .finish_non_exhaustive()
823 }
824}
825
826pub struct CreationCorrelation<P, Occurrence>
849where
850 P: Protocol,
851{
852 id: CreationId,
853 occurrence: PhantomData<fn() -> (P, Occurrence)>,
854}
855
856impl<P, Occurrence> CreationCorrelation<P, Occurrence>
857where
858 P: Protocol,
859{
860 #[must_use]
861 pub const fn new(id: CreationId) -> Self {
862 Self {
863 id,
864 occurrence: PhantomData,
865 }
866 }
867
868 #[must_use]
869 pub const fn id(self) -> CreationId {
870 self.id
871 }
872}
873
874impl<P, Occurrence> Copy for CreationCorrelation<P, Occurrence> where P: Protocol {}
875
876impl<P, Occurrence> Clone for CreationCorrelation<P, Occurrence>
877where
878 P: Protocol,
879{
880 fn clone(&self) -> Self {
881 *self
882 }
883}
884
885impl<P, Occurrence> core::fmt::Debug for CreationCorrelation<P, Occurrence>
886where
887 P: Protocol,
888{
889 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
890 formatter
891 .debug_tuple("CreationCorrelation")
892 .field(&self.id)
893 .finish()
894 }
895}
896
897impl<P, Occurrence> PartialEq for CreationCorrelation<P, Occurrence>
898where
899 P: Protocol,
900{
901 fn eq(&self, other: &Self) -> bool {
902 self.id == other.id
903 }
904}
905
906impl<P, Occurrence> Eq for CreationCorrelation<P, Occurrence> where P: Protocol {}
907
908pub struct ChildDelivery<P, Occurrence>
915where
916 P: Protocol,
917{
918 pub creation: CreationId,
919 pub message: P::Msg,
920 occurrence: PhantomData<fn() -> Occurrence>,
921}
922
923pub struct ChildInput<Child, Source, Input, Occurrence>
936where
937 Child: Behavior,
938{
939 pub creation: CreationId,
941 pub input: Input,
943 marker: PhantomData<fn() -> (Child, Source, Occurrence)>,
944}
945
946#[derive(Clone, Copy, Debug, Eq, PartialEq)]
948pub enum ChildDeliveryReason {
949 MissingBinding,
950 ClosedRecipient,
951}
952
953#[derive(Clone, Copy, Debug, Eq, PartialEq)]
955pub enum ChildInputReason {
956 MissingBinding,
957 ClosedControlLane,
958}
959
960#[derive(Debug, Clone, Copy, PartialEq, Eq)]
967pub struct ChildReport<R> {
968 pub child: CreationId,
970 pub report: R,
972}
973
974impl<R> ChildReport<R> {
975 #[must_use]
977 pub const fn new(child: CreationId, report: R) -> Self {
978 Self { child, report }
979 }
980}
981
982impl<R> From<(CreationId, crate::ReportToParent<R>)> for ChildReport<R> {
983 fn from((child, request): (CreationId, crate::ReportToParent<R>)) -> Self {
984 Self::new(child, request.into_inner())
985 }
986}
987
988impl<Child, Source, Input, Occurrence> ChildInput<Child, Source, Input, Occurrence>
989where
990 Child: Behavior,
991 Child::Event: crate::ChildInputIngress<Source, Input>,
992{
993 #[must_use]
995 pub const fn after(creation: CreationId, input: Input) -> Self {
996 Self {
997 creation,
998 input,
999 marker: PhantomData,
1000 }
1001 }
1002}
1003
1004impl<Child, Source, Input, Occurrence> Clone for ChildInput<Child, Source, Input, Occurrence>
1005where
1006 Child: Behavior,
1007 Input: Clone,
1008{
1009 fn clone(&self) -> Self {
1010 Self {
1011 creation: self.creation,
1012 input: self.input.clone(),
1013 marker: PhantomData,
1014 }
1015 }
1016}
1017
1018impl<P, Occurrence> ChildDelivery<P, Occurrence>
1019where
1020 P: Protocol,
1021{
1022 #[must_use]
1023 pub const fn after(creation: CreationId, message: P::Msg) -> Self {
1024 Self {
1025 creation,
1026 message,
1027 occurrence: PhantomData,
1028 }
1029 }
1030}
1031
1032impl<P, Occurrence> Clone for ChildDelivery<P, Occurrence>
1033where
1034 P: Protocol,
1035 P::Msg: Clone,
1036{
1037 fn clone(&self) -> Self {
1038 Self {
1039 creation: self.creation,
1040 message: self.message.clone(),
1041 occurrence: PhantomData,
1042 }
1043 }
1044}
1045
1046impl<P, Occurrence> ActionItem for ChildDelivery<P, Occurrence>
1047where
1048 P: Protocol,
1049 P::Msg: Send,
1050{
1051 type Accepted = ();
1052 type Rejection = ChildDeliveryReason;
1053 type Prerequisite = CreationCorrelation<P, Occurrence>;
1054}
1055
1056impl<Child, Source, Input, Occurrence> ActionItem for ChildInput<Child, Source, Input, Occurrence>
1057where
1058 Child: Behavior,
1059 Input: Send,
1060{
1061 type Accepted = ();
1062 type Rejection = ChildInputReason;
1063 type Prerequisite = CreationCorrelation<Child::Protocol, Occurrence>;
1064}
1065
1066pub trait EstablishChild<Occurrence, C>
1132where
1133 C: Behavior,
1134 BehaviorAddr<C>: EndpointAddress,
1135{
1136 fn establish_child(
1138 &mut self,
1139 creation: RoutedCreation<BehaviorAddr<C>, C>,
1140 ) -> impl Future<
1141 Output = ItemSettlement<
1142 RoutedCreation<BehaviorAddr<C>, C>,
1143 ChildCreationOutcome<C, Occurrence>,
1144 CreationRejection,
1145 Never,
1146 >,
1147 > + Send;
1148}
1149
1150#[doc(hidden)]
1155pub trait ChildCreationProduct<A: Address, Occurrence>: Sized {
1156 type Result;
1157}
1158
1159pub trait DispatchBirth<A: Address, Host>: ChildCreationProduct<A, ChildHead> + Sized {
1168 fn dispatch_birth(
1171 self,
1172 id: CreationId,
1173 route: A::Nonce,
1174 kind: CreationKind,
1175 host: &mut Host,
1176 ) -> impl Future<
1177 Output = ItemSettlement<
1178 RoutedCreation<A, Self>,
1179 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1180 CreationRejection,
1181 Never,
1182 >,
1183 > + Send;
1184}
1185
1186trait CreateSelectedChild<A: Address, Occurrence, Host>:
1187 ChildCreationProduct<A, Occurrence> + Sized
1188{
1189 fn dispatch_birth_at(
1190 self,
1191 id: CreationId,
1192 route: A::Nonce,
1193 kind: CreationKind,
1194 host: &mut Host,
1195 ) -> impl Future<
1196 Output = ItemSettlement<
1197 RoutedCreation<A, Self>,
1198 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1199 CreationRejection,
1200 Never,
1201 >,
1202 > + Send;
1203}
1204
1205impl<A, Child, Host> DispatchBirth<A, Host> for Child
1206where
1207 A: Address,
1208 Child: CreateSelectedChild<A, ChildHead, Host>,
1209{
1210 fn dispatch_birth(
1211 self,
1212 id: CreationId,
1213 route: A::Nonce,
1214 kind: CreationKind,
1215 host: &mut Host,
1216 ) -> impl Future<
1217 Output = ItemSettlement<
1218 RoutedCreation<A, Self>,
1219 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1220 CreationRejection,
1221 Never,
1222 >,
1223 > + Send {
1224 self.dispatch_birth_at(id, route, kind, host)
1225 }
1226}
1227
1228#[derive(Debug, Clone, PartialEq, Eq)]
1312pub enum ChildChoice<Head, Tail> {
1313 Head(Head),
1315 Tail(Tail),
1317}
1318
1319#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1321pub struct ChildHead;
1322
1323#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1325pub struct ChildTail<Position>(PhantomData<fn() -> Position>);
1326
1327pub trait ChildPosition<Children, Child: Behavior>: sealed::ChildPosition {}
1380
1381impl sealed::ChildPosition for ChildHead {}
1382
1383impl<Child: Behavior> ChildPosition<Child, Child> for ChildHead {}
1384
1385impl<Head: Behavior, Tail> ChildPosition<ChildChoice<Head, Tail>, Head> for ChildHead {}
1386
1387impl<Position> sealed::ChildPosition for ChildTail<Position> {}
1388
1389impl<Head, Tail, Position, Child> ChildPosition<ChildChoice<Head, Tail>, Child>
1390 for ChildTail<Position>
1391where
1392 Child: Behavior,
1393 Position: ChildPosition<Tail, Child>,
1394{
1395}
1396
1397pub trait BirthNodeAppend<Tail>: sealed::BirthNode + Sized
1419where
1420 Tail: sealed::BirthNode,
1421{
1422 type Output: sealed::BirthNode;
1425
1426 fn append_prefix(self) -> Self::Output;
1429
1430 fn append_tail(tail: Tail) -> Self::Output;
1432
1433 #[must_use]
1435 fn append_creations<A: Address>(
1436 prefix: Creations<CreateChild<A, Self>>,
1437 tail: Creations<CreateChild<A, Tail>>,
1438 ) -> Creations<CreateChild<A, Self::Output>> {
1439 let mut combined = Vec::with_capacity(prefix.len() + tail.len());
1440 combined.extend(prefix.into_iter().map(|creation| {
1441 let (id, child, kind) = creation.into_parts();
1442 CreateChild::from_parts(id, Self::append_prefix(child), kind)
1443 }));
1444 combined.extend(tail.into_iter().map(|creation| {
1445 let (id, child, kind) = creation.into_parts();
1446 CreateChild::from_parts(id, Self::append_tail(child), kind)
1447 }));
1448 Creations::from_items(combined)
1449 }
1450}
1451
1452impl<Tail> BirthNodeAppend<Tail> for Never
1453where
1454 Tail: sealed::BirthNode,
1455{
1456 type Output = Tail;
1457
1458 fn append_prefix(self) -> Self::Output {
1459 match self {}
1460 }
1461
1462 fn append_tail(tail: Tail) -> Self::Output {
1463 tail
1464 }
1465}
1466
1467impl<Node> BirthNodeAppend<Never> for Node
1468where
1469 Node: sealed::NonEmptyBirthNode,
1470{
1471 type Output = Node;
1472
1473 fn append_prefix(self) -> Self::Output {
1474 self
1475 }
1476
1477 fn append_tail(tail: Never) -> Self::Output {
1478 match tail {}
1479 }
1480}
1481
1482impl<Child, Tail> BirthNodeAppend<Tail> for Child
1483where
1484 Child: Behavior,
1485 Tail: sealed::NonEmptyBirthNode,
1486{
1487 type Output = ChildChoice<Child, Tail>;
1488
1489 fn append_prefix(self) -> Self::Output {
1490 ChildChoice::Head(self)
1491 }
1492
1493 fn append_tail(tail: Tail) -> Self::Output {
1494 ChildChoice::Tail(tail)
1495 }
1496}
1497
1498impl<Head, Rest, Tail> BirthNodeAppend<Tail> for ChildChoice<Head, Rest>
1499where
1500 Head: Behavior,
1501 Rest: sealed::BirthNode + BirthNodeAppend<Tail>,
1502 Tail: sealed::NonEmptyBirthNode,
1503 Rest::Output: sealed::BirthNode,
1504{
1505 type Output = ChildChoice<Head, Rest::Output>;
1506
1507 fn append_prefix(self) -> Self::Output {
1508 match self {
1509 ChildChoice::Head(head) => ChildChoice::Head(head),
1510 ChildChoice::Tail(rest) => ChildChoice::Tail(rest.append_prefix()),
1511 }
1512 }
1513
1514 fn append_tail(tail: Tail) -> Self::Output {
1515 ChildChoice::Tail(Rest::append_tail(tail))
1516 }
1517}
1518
1519impl<Parent: Behavior> ChildOccurrence<Parent> for ChildHead {
1520 type Resolution = StructuralChildOccurrence<Self>;
1521}
1522
1523impl<Parent: Behavior, Position> ChildOccurrence<Parent> for ChildTail<Position> {
1524 type Resolution = StructuralChildOccurrence<Self>;
1525}
1526
1527#[doc(hidden)]
1534pub trait ChildOccurrenceResolution<Parent: Behavior, Occurrence>:
1535 sealed::ChildOccurrenceDescriptor + sealed::OccurrenceResolution<Parent, Occurrence>
1536{
1537}
1538
1539impl<Parent, Occurrence> ChildOccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1540where
1541 Parent: Behavior,
1542 Occurrence: ChildRole<Parent>,
1543{
1544}
1545
1546impl<Parent: Behavior> ChildOccurrenceResolution<Parent, ChildHead>
1547 for StructuralChildOccurrence<ChildHead>
1548{
1549}
1550
1551impl<Parent: Behavior, Position> ChildOccurrenceResolution<Parent, ChildTail<Position>>
1552 for StructuralChildOccurrence<ChildTail<Position>>
1553{
1554}
1555
1556#[doc(hidden)]
1558pub trait ResolveChildOccurrenceDescriptor<Emitter: Behavior, Occurrence>:
1559 sealed::ChildOccurrenceDescriptor + sealed::ResolveDescriptor<Emitter, Occurrence>
1560{
1561 type Child: Behavior;
1562 type Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Self::Child>;
1563}
1564
1565impl<Emitter, Occurrence, Position> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1566 for StructuralChildOccurrence<Position>
1567where
1568 Emitter: Behavior,
1569 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1570 Position: ChildPosition<
1571 <Emitter::Birth as BirthMode>::Child,
1572 <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child,
1573 >,
1574{
1575 type Child = <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child;
1576 type Position = Position;
1577}
1578
1579impl<Emitter, Occurrence> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1580 for DeclaredChildOccurrence
1581where
1582 Emitter:
1583 Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol> + BehaviorBase,
1584 Emitter::Base: Behavior,
1585 Occurrence: ChildRole<Emitter::Base>,
1586 <Emitter::Birth as BirthMode>::Child:
1587 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1588 Occurrence::Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1589{
1590 type Child = Occurrence::Child;
1591 type Position = Occurrence::Position;
1592}
1593
1594#[doc(hidden)]
1596pub trait BirthNodeAt<Position>: sealed::BirthNode {
1597 type Child: Behavior;
1598}
1599
1600impl<Child: Behavior> BirthNodeAt<ChildHead> for Child {
1601 type Child = Child;
1602}
1603
1604impl<Head: Behavior, Tail> BirthNodeAt<ChildHead> for ChildChoice<Head, Tail>
1605where
1606 Tail: sealed::BirthNode,
1607{
1608 type Child = Head;
1609}
1610
1611impl<Head, Tail, Position> BirthNodeAt<ChildTail<Position>> for ChildChoice<Head, Tail>
1612where
1613 Head: Behavior,
1614 Tail: BirthNodeAt<Position>,
1615{
1616 type Child = <Tail as BirthNodeAt<Position>>::Child;
1617}
1618
1619pub trait ChildOccurrenceShape {
1646 type Empty;
1648
1649 type Member<Occurrence, Child: Behavior, Tail>;
1651}
1652
1653pub trait ChildOccurrenceProduct<Shape>: sealed::BirthNode
1680where
1681 Shape: ChildOccurrenceShape,
1682{
1683 type Product;
1685}
1686
1687#[doc(hidden)]
1690pub trait ChildOccurrenceProductAt<Occurrence, Shape>: sealed::BirthNode
1691where
1692 Shape: ChildOccurrenceShape,
1693{
1694 type Product;
1695}
1696
1697impl<Node, Shape> ChildOccurrenceProduct<Shape> for Node
1698where
1699 Node: ChildOccurrenceProductAt<ChildHead, Shape>,
1700 Shape: ChildOccurrenceShape,
1701{
1702 type Product = <Node as ChildOccurrenceProductAt<ChildHead, Shape>>::Product;
1703}
1704
1705impl<Occurrence, Shape, Child> ChildOccurrenceProductAt<Occurrence, Shape> for Child
1706where
1707 Shape: ChildOccurrenceShape,
1708 Child: Behavior,
1709{
1710 type Product = Shape::Member<Occurrence, Child, Shape::Empty>;
1711}
1712
1713impl<Occurrence, Shape, Head, Tail> ChildOccurrenceProductAt<Occurrence, Shape>
1714 for ChildChoice<Head, Tail>
1715where
1716 Shape: ChildOccurrenceShape,
1717 Head: Behavior,
1718 Tail: ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>,
1719{
1720 type Product = Shape::Member<
1721 Occurrence,
1722 Head,
1723 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1724 >;
1725}
1726
1727impl<Occurrence, Shape> ChildOccurrenceProductAt<Occurrence, Shape> for Never
1728where
1729 Shape: ChildOccurrenceShape,
1730{
1731 type Product = Shape::Empty;
1732}
1733
1734pub type ChildOccurrences<Node, Shape> = <Node as ChildOccurrenceProduct<Shape>>::Product;
1736
1737mod sealed {
1738 use super::{
1739 Behavior, BehaviorBase, BirthMode, BirthNodeAt, ChildChoice, ChildHead, ChildOccurrence,
1740 ChildRole, ChildTail, DeclaredChildOccurrence, Never, ResolveChildOccurrenceDescriptor,
1741 StructuralChildOccurrence,
1742 };
1743
1744 pub trait BirthNode {}
1745
1746 pub trait NonEmptyBirthNode: BirthNode {}
1747
1748 impl<Child: Behavior> BirthNode for Child {}
1749 impl<Child: Behavior> NonEmptyBirthNode for Child {}
1750
1751 impl<Head, Tail> BirthNode for ChildChoice<Head, Tail>
1752 where
1753 Head: Behavior,
1754 Tail: BirthNode,
1755 {
1756 }
1757
1758 impl<Head, Tail> NonEmptyBirthNode for ChildChoice<Head, Tail>
1759 where
1760 Head: Behavior,
1761 Tail: BirthNode,
1762 {
1763 }
1764
1765 impl BirthNode for Never {}
1766
1767 pub trait ChildPosition {}
1768 pub trait ChildProduct {}
1769
1770 pub trait ChildOccurrenceDescriptor {}
1771
1772 impl ChildOccurrenceDescriptor for DeclaredChildOccurrence {}
1773
1774 impl<Position> ChildOccurrenceDescriptor for StructuralChildOccurrence<Position> {}
1775
1776 pub trait OccurrenceResolution<Parent: Behavior, Occurrence> {}
1777
1778 impl<Parent, Occurrence> OccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1779 where
1780 Parent: Behavior,
1781 Occurrence: ChildRole<Parent>,
1782 {
1783 }
1784
1785 impl<Parent: Behavior> OccurrenceResolution<Parent, ChildHead>
1786 for StructuralChildOccurrence<ChildHead>
1787 {
1788 }
1789
1790 impl<Parent: Behavior, Position> OccurrenceResolution<Parent, ChildTail<Position>>
1791 for StructuralChildOccurrence<ChildTail<Position>>
1792 {
1793 }
1794
1795 pub trait ResolveDescriptor<Emitter: Behavior, Occurrence> {}
1796
1797 impl<Emitter, Occurrence, Position> ResolveDescriptor<Emitter, Occurrence>
1798 for StructuralChildOccurrence<Position>
1799 where
1800 Emitter: Behavior,
1801 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1802 {
1803 }
1804
1805 impl<Emitter, Occurrence> ResolveDescriptor<Emitter, Occurrence> for DeclaredChildOccurrence
1806 where
1807 Emitter: Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol>
1808 + BehaviorBase,
1809 Emitter::Base: Behavior,
1810 Occurrence: ChildRole<Emitter::Base>,
1811 <Emitter::Birth as BirthMode>::Child:
1812 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1813 Occurrence::Position:
1814 super::ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1815 {
1816 }
1817
1818 pub trait ResolveChildOccurrence<Occurrence> {}
1819
1820 impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
1821 where
1822 Emitter: Behavior + BehaviorBase,
1823 Emitter::Base: Behavior,
1824 Occurrence: ChildOccurrence<Emitter::Base>,
1825 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
1826 {
1827 }
1828}
1829
1830#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1832pub struct NoChildren;
1833
1834impl sealed::ChildProduct for NoChildren {}
1835
1836pub struct ChildCons<A: Address, C, Earlier> {
1838 creation: CreateChild<A, C>,
1839 earlier: Earlier,
1840}
1841
1842impl<A: Address, C, Earlier> sealed::ChildProduct for ChildCons<A, C, Earlier> {}
1843
1844pub struct Children<A: Address, Product = NoChildren> {
1850 product: Product,
1851 address: PhantomData<fn() -> A>,
1852}
1853
1854pub trait ChildProduct<A: Address>: sealed::ChildProduct + Sized {
1856 type Choice: BirthNodeAppend<Never>;
1858
1859 #[doc(hidden)]
1860 fn stage(self) -> Vec<CreateChild<A, Self::Choice>>;
1861}
1862
1863impl<A: Address> ChildProduct<A> for NoChildren {
1864 type Choice = Never;
1865
1866 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1867 Vec::new()
1868 }
1869}
1870
1871impl<A, C, Earlier> ChildProduct<A> for ChildCons<A, C, Earlier>
1872where
1873 A: Address,
1874 C: Behavior,
1875 C::Protocol: Protocol<Addr = A>,
1876 Earlier: ChildProduct<A>,
1877{
1878 type Choice = ChildChoice<C, Earlier::Choice>;
1879
1880 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1881 let earlier = self.earlier.stage();
1882 let mut creates = earlier
1883 .into_iter()
1884 .map(|creation| {
1885 let (id, child, kind) = creation.into_parts();
1886 CreateChild::from_parts(id, ChildChoice::Tail(child), kind)
1887 })
1888 .collect::<Vec<_>>();
1889 let (id, child, kind) = self.creation.into_parts();
1890 creates.push(CreateChild::from_parts(id, ChildChoice::Head(child), kind));
1891 creates
1892 }
1893}
1894
1895impl<A: Address> Children<A, NoChildren> {
1896 #[must_use]
1898 pub const fn new() -> Self {
1899 Self {
1900 product: NoChildren,
1901 address: PhantomData,
1902 }
1903 }
1904}
1905
1906impl<A: Address> Default for Children<A, NoChildren> {
1907 fn default() -> Self {
1908 Self::new()
1909 }
1910}
1911
1912impl<A: Address, Product> Children<A, Product> {
1913 #[must_use]
1915 pub fn create<C>(self, creation: CreateChild<A, C>) -> Children<A, ChildCons<A, C, Product>>
1916 where
1917 C: Behavior,
1918 C::Protocol: Protocol<Addr = A>,
1919 {
1920 Children {
1921 product: ChildCons {
1922 creation,
1923 earlier: self.product,
1924 },
1925 address: PhantomData,
1926 }
1927 }
1928
1929 #[must_use]
1931 pub fn child<C>(self, id: CreationId, child: C) -> Children<A, ChildCons<A, C, Product>>
1932 where
1933 C: Behavior,
1934 C::Protocol: Protocol<Addr = A>,
1935 {
1936 self.create(CreateChild::birth(id, child))
1937 }
1938}
1939
1940impl<A, Product> Children<A, Product>
1941where
1942 A: Address,
1943 Product: ChildProduct<A>,
1944{
1945 #[must_use]
1947 pub fn into_creates(self) -> Creations<CreateChild<A, Product::Choice>> {
1948 Creations::from_items(self.product.stage())
1949 }
1950}
1951
1952impl<A, Occurrence, Head, Tail> ChildCreationProduct<A, Occurrence> for ChildChoice<Head, Tail>
1953where
1954 A: EndpointAddress,
1955 Head: Behavior,
1956 Head::Protocol: Protocol<Addr = A>,
1957 Tail: ChildCreationProduct<A, ChildTail<Occurrence>>,
1958{
1959 type Result = ChildChoice<
1960 ChildCreationOutcome<Head, Occurrence>,
1961 <Tail as ChildCreationProduct<A, ChildTail<Occurrence>>>::Result,
1962 >;
1963}
1964
1965impl<A, Occurrence, Head, Tail, Host> CreateSelectedChild<A, Occurrence, Host>
1966 for ChildChoice<Head, Tail>
1967where
1968 A: EndpointAddress,
1969 A::Nonce: Send,
1970 Head: Behavior + Send,
1971 Head::Protocol: Protocol<Addr = A>,
1972 Tail: CreateSelectedChild<A, ChildTail<Occurrence>, Host> + Send,
1973 Host: EstablishChild<Occurrence, Head> + Send,
1974{
1975 async fn dispatch_birth_at(
1976 self,
1977 id: CreationId,
1978 route: A::Nonce,
1979 kind: CreationKind,
1980 host: &mut Host,
1981 ) -> ItemSettlement<
1982 RoutedCreation<A, Self>,
1983 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1984 CreationRejection,
1985 Never,
1986 > {
1987 match self {
1988 Self::Head(child) => {
1989 let creation = RoutedCreation::new(CreateChild::from_parts(id, child, kind), route);
1990 match host.establish_child(creation).await {
1991 ItemSettlement::Accepted(receipt) => {
1992 ItemSettlement::Accepted(ChildChoice::Head(receipt))
1993 }
1994 ItemSettlement::Rejected { item, reason } => {
1995 let (creation, route) = item.into_parts();
1996 let (id, child, kind) = creation.into_parts();
1997 ItemSettlement::Rejected {
1998 item: RoutedCreation::new(
1999 CreateChild::from_parts(id, Self::Head(child), kind),
2000 route,
2001 ),
2002 reason,
2003 }
2004 }
2005 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2006 ItemSettlement::Corrupt { item, fault } => {
2007 let (creation, route) = item.into_parts();
2008 let (id, child, kind) = creation.into_parts();
2009 ItemSettlement::Corrupt {
2010 item: RoutedCreation::new(
2011 CreateChild::from_parts(id, Self::Head(child), kind),
2012 route,
2013 ),
2014 fault,
2015 }
2016 }
2017 }
2018 }
2019 Self::Tail(tail) => match tail.dispatch_birth_at(id, route, kind, host).await {
2020 ItemSettlement::Accepted(receipt) => {
2021 ItemSettlement::Accepted(ChildChoice::Tail(receipt))
2022 }
2023 ItemSettlement::Rejected { item, reason } => {
2024 let (creation, route) = item.into_parts();
2025 let (id, child, kind) = creation.into_parts();
2026 ItemSettlement::Rejected {
2027 item: RoutedCreation::new(
2028 CreateChild::from_parts(id, Self::Tail(child), kind),
2029 route,
2030 ),
2031 reason,
2032 }
2033 }
2034 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
2035 ItemSettlement::Corrupt { item, fault } => {
2036 let (creation, route) = item.into_parts();
2037 let (id, child, kind) = creation.into_parts();
2038 ItemSettlement::Corrupt {
2039 item: RoutedCreation::new(
2040 CreateChild::from_parts(id, Self::Tail(child), kind),
2041 route,
2042 ),
2043 fault,
2044 }
2045 }
2046 },
2047 }
2048 }
2049}
2050
2051impl<A, Occurrence> ChildCreationProduct<A, Occurrence> for Never
2052where
2053 A: Address,
2054{
2055 type Result = Never;
2056}
2057
2058impl<A, Occurrence, Host> CreateSelectedChild<A, Occurrence, Host> for Never
2059where
2060 A: Address,
2061{
2062 fn dispatch_birth_at(
2063 self,
2064 _id: CreationId,
2065 _route: A::Nonce,
2066 _kind: CreationKind,
2067 _host: &mut Host,
2068 ) -> impl Future<
2069 Output = ItemSettlement<
2070 RoutedCreation<A, Self>,
2071 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2072 CreationRejection,
2073 Never,
2074 >,
2075 > + Send {
2076 async move { match self {} }
2077 }
2078}
2079
2080impl<A, Occurrence, C> ChildCreationProduct<A, Occurrence> for C
2081where
2082 A: EndpointAddress,
2083 C: Behavior,
2084 C::Protocol: Protocol<Addr = A>,
2085{
2086 type Result = ChildCreationOutcome<C, Occurrence>;
2087}
2088
2089impl<A, Occurrence, C, Host> CreateSelectedChild<A, Occurrence, Host> for C
2090where
2091 A: EndpointAddress,
2092 C: Behavior,
2093 C::Protocol: Protocol<Addr = A>,
2094 Host: EstablishChild<Occurrence, C>,
2095{
2096 fn dispatch_birth_at(
2097 self,
2098 id: CreationId,
2099 route: A::Nonce,
2100 kind: CreationKind,
2101 host: &mut Host,
2102 ) -> impl Future<
2103 Output = ItemSettlement<
2104 RoutedCreation<A, Self>,
2105 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2106 CreationRejection,
2107 Never,
2108 >,
2109 > + Send {
2110 host.establish_child(RoutedCreation::new(
2111 CreateChild::from_parts(id, self, kind),
2112 route,
2113 ))
2114 }
2115}
2116
2117pub trait BirthMode {
2119 type Child;
2120}
2121
2122pub struct NoBirthProtocols;
2124
2125pub struct BirthProtocol<P: Protocol, Tail> {
2127 protocol: PhantomData<fn() -> P>,
2128 tail: PhantomData<fn() -> Tail>,
2129}
2130
2131pub struct BirthProtocolHead;
2133
2134pub struct BirthProtocolTail<Position>(PhantomData<fn() -> Position>);
2136
2137pub trait BirthProtocolAt<P: Protocol, Position> {}
2139
2140impl<P: Protocol, Tail> BirthProtocolAt<P, BirthProtocolHead> for BirthProtocol<P, Tail> {}
2141
2142impl<Head, Tail, P, Position> BirthProtocolAt<P, BirthProtocolTail<Position>>
2143 for BirthProtocol<Head, Tail>
2144where
2145 Head: Protocol,
2146 P: Protocol,
2147 Tail: BirthProtocolAt<P, Position>,
2148{
2149}
2150
2151pub trait BirthProtocolProduct {
2153 type Append<Tail: BirthProtocolProduct>: BirthProtocolProduct;
2154}
2155
2156impl BirthProtocolProduct for NoBirthProtocols {
2157 type Append<Tail: BirthProtocolProduct> = Tail;
2158}
2159
2160impl<P, Rest> BirthProtocolProduct for BirthProtocol<P, Rest>
2161where
2162 P: Protocol,
2163 Rest: BirthProtocolProduct,
2164{
2165 type Append<Tail: BirthProtocolProduct> = BirthProtocol<P, Rest::Append<Tail>>;
2166}
2167
2168pub trait BirthProtocols: Behavior {
2174 type Protocols: BirthProtocolProduct;
2175}
2176
2177impl<B> BirthProtocols for B
2178where
2179 B: Behavior,
2180 B::Birth: BirthModeProtocols,
2181{
2182 type Protocols = BirthProtocol<B::Protocol, <B::Birth as BirthModeProtocols>::Protocols>;
2183}
2184
2185#[doc(hidden)]
2186pub trait BirthModeProtocols {
2187 type Protocols: BirthProtocolProduct;
2188}
2189
2190impl<M> BirthModeProtocols for M
2191where
2192 M: BirthMode,
2193 M::Child: BirthNodeProtocols,
2194{
2195 type Protocols = <M::Child as BirthNodeProtocols>::Protocols;
2196}
2197
2198#[doc(hidden)]
2199pub trait BirthNodeProtocols {
2200 type Protocols: BirthProtocolProduct;
2201}
2202
2203impl<B> BirthNodeProtocols for B
2204where
2205 B: BirthProtocols,
2206{
2207 type Protocols = B::Protocols;
2208}
2209
2210impl<Head, Tail> BirthNodeProtocols for ChildChoice<Head, Tail>
2211where
2212 Head: BirthNodeProtocols,
2213 Tail: BirthNodeProtocols,
2214{
2215 type Protocols = <Head::Protocols as BirthProtocolProduct>::Append<Tail::Protocols>;
2216}
2217
2218impl BirthNodeProtocols for Never {
2219 type Protocols = NoBirthProtocols;
2220}
2221
2222#[doc(hidden)]
2227pub trait BirthNodeLogicalHosts {
2228 type LogicalHosts: BirthProtocolProduct;
2229}
2230
2231impl<B> BirthNodeLogicalHosts for B
2232where
2233 B: crate::LogicalHostRequirements,
2234{
2235 type LogicalHosts = B::LogicalHosts;
2236}
2237
2238impl<Head, Tail> BirthNodeLogicalHosts for ChildChoice<Head, Tail>
2239where
2240 Head: BirthNodeLogicalHosts,
2241 Tail: BirthNodeLogicalHosts,
2242{
2243 type LogicalHosts = <Head::LogicalHosts as BirthProtocolProduct>::Append<Tail::LogicalHosts>;
2244}
2245
2246impl BirthNodeLogicalHosts for Never {
2247 type LogicalHosts = NoBirthProtocols;
2248}
2249
2250#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2252pub struct NoBirths;
2253
2254impl BirthMode for NoBirths {
2255 type Child = Never;
2256}
2257
2258#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2260pub struct Births<C>(PhantomData<fn() -> C>);
2261
2262impl<C> BirthMode for Births<C> {
2263 type Child = C;
2264}
2265
2266#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2274pub struct RetirementBirths<C>(PhantomData<fn() -> C>);
2275
2276impl<C> BirthMode for RetirementBirths<C> {
2277 type Child = C;
2278}
2279
2280#[cfg(test)]
2281mod tests {
2282 use super::*;
2283 use crate::{Actions, BehaviorActed, NoBirths, User};
2284
2285 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2286 struct TestAddr(u64);
2287
2288 impl Address for TestAddr {
2289 type Nonce = u64;
2290 }
2291
2292 struct TestEndpoint<P>(PhantomData<fn() -> P>);
2293
2294 impl<P> Clone for TestEndpoint<P> {
2295 fn clone(&self) -> Self {
2296 *self
2297 }
2298 }
2299
2300 impl<P> Copy for TestEndpoint<P> {}
2301
2302 struct TestInstalled<B: Behavior> {
2303 endpoint: TestEndpoint<B::Protocol>,
2304 control: std::sync::mpsc::Sender<B::Event>,
2305 }
2306
2307 impl<B: Behavior> Clone for TestInstalled<B> {
2308 fn clone(&self) -> Self {
2309 Self {
2310 endpoint: self.endpoint,
2311 control: self.control.clone(),
2312 }
2313 }
2314 }
2315
2316 impl EndpointAddress for TestAddr {
2317 type Established<P>
2318 = TestEndpoint<P>
2319 where
2320 P: Protocol<Addr = Self>;
2321
2322 type Installed<B>
2323 = TestInstalled<B>
2324 where
2325 B: Behavior<Protocol: Protocol<Addr = Self>>;
2326
2327 fn recipient<B>(installed: &Self::Installed<B>) -> Self::Established<B::Protocol>
2328 where
2329 B: Behavior<Protocol: Protocol<Addr = Self>>,
2330 {
2331 installed.endpoint
2332 }
2333 }
2334
2335 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2336 struct Child;
2337
2338 struct SharedProtocol;
2339
2340 impl behavior::Protocol for SharedProtocol {
2341 type Addr = TestAddr;
2342 type Msg = u8;
2343 }
2344
2345 struct Primary;
2346 struct Fallback;
2347
2348 macro_rules! shared_protocol_behavior {
2349 ($behavior:ty, $birth:ty) => {
2350 impl Behavior for $behavior {
2351 type Protocol = SharedProtocol;
2352 type Event = User<TestAddr, u8>;
2353 type Sends = Vec<Never>;
2354 type Ph = Never;
2355 type Error = Never;
2356 type Birth = $birth;
2357
2358 fn transition(
2359 &mut self,
2360 _: crate::ActiveTurn,
2361 _: Self::Event,
2362 ) -> BehaviorActed<Self> {
2363 Ok(Actions::cont())
2364 }
2365 }
2366 };
2367 }
2368
2369 shared_protocol_behavior!(Primary, Births<Child>);
2370 shared_protocol_behavior!(Fallback, NoBirths);
2371
2372 impl behavior::Protocol for Child {
2373 type Addr = TestAddr;
2374 type Msg = u8;
2375 }
2376
2377 impl Behavior for Child {
2378 type Protocol = Self;
2379 type Event = User<TestAddr, u8>;
2380 type Sends = Vec<Never>;
2381 type Ph = Never;
2382 type Error = Never;
2383 type Birth = NoBirths;
2384
2385 fn transition(&mut self, _: crate::ActiveTurn, _: Self::Event) -> BehaviorActed<Self> {
2386 Ok(Actions::cont())
2387 }
2388 }
2389
2390 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2391 enum ChildPlan {
2392 CreateChild,
2393 RejectBeforeTransfer,
2394 }
2395
2396 struct RecordingHost {
2397 calls: usize,
2398 observed: Vec<(CreationId, u64, CreationKind)>,
2399 plan: ChildPlan,
2400 control_receivers: Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2401 }
2402
2403 #[derive(Debug, PartialEq, Eq)]
2404 enum SharedCreation {
2405 Primary(CreationId, u64),
2406 Fallback(CreationId, u64),
2407 }
2408
2409 #[derive(Default)]
2410 struct SharedProtocolHost(
2411 Vec<SharedCreation>,
2412 Vec<std::sync::mpsc::Receiver<User<TestAddr, u8>>>,
2413 );
2414
2415 impl EstablishChild<ChildHead, Primary> for SharedProtocolHost {
2416 async fn establish_child(
2417 &mut self,
2418 creation: RoutedCreation<TestAddr, Primary>,
2419 ) -> ItemSettlement<
2420 RoutedCreation<TestAddr, Primary>,
2421 ChildCreationOutcome<Primary, ChildHead>,
2422 CreationRejection,
2423 Never,
2424 > {
2425 let id = creation.id();
2426 let kind = creation.kind();
2427 let route = creation.route();
2428 let (creation, _) = creation.into_parts();
2429 let (_, _child, _) = creation.into_parts();
2430 self.0.push(SharedCreation::Primary(id, route));
2431 let (control, receiver) = std::sync::mpsc::channel();
2432 self.1.push(receiver);
2433 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2434 id,
2435 kind,
2436 EstablishedActor::issued(TestInstalled {
2437 endpoint: TestEndpoint(PhantomData),
2438 control,
2439 }),
2440 )))
2441 }
2442 }
2443
2444 impl EstablishChild<ChildTail<ChildHead>, Fallback> for SharedProtocolHost {
2445 async fn establish_child(
2446 &mut self,
2447 creation: RoutedCreation<TestAddr, Fallback>,
2448 ) -> ItemSettlement<
2449 RoutedCreation<TestAddr, Fallback>,
2450 ChildCreationOutcome<Fallback, ChildTail<ChildHead>>,
2451 CreationRejection,
2452 Never,
2453 > {
2454 let id = creation.id();
2455 let kind = creation.kind();
2456 let route = creation.route();
2457 let (creation, _) = creation.into_parts();
2458 let (_, _child, _) = creation.into_parts();
2459 self.0.push(SharedCreation::Fallback(id, route));
2460 let (control, receiver) = std::sync::mpsc::channel();
2461 self.1.push(receiver);
2462 ItemSettlement::Accepted(ChildCreationOutcome::Established(CommittedChild::new(
2463 id,
2464 kind,
2465 EstablishedActor::issued(TestInstalled {
2466 endpoint: TestEndpoint(PhantomData),
2467 control,
2468 }),
2469 )))
2470 }
2471 }
2472
2473 impl EstablishChild<ChildHead, Child> for RecordingHost {
2474 async fn establish_child(
2475 &mut self,
2476 creation: RoutedCreation<TestAddr, Child>,
2477 ) -> ItemSettlement<
2478 RoutedCreation<TestAddr, Child>,
2479 ChildCreationOutcome<Child, ChildHead>,
2480 CreationRejection,
2481 Never,
2482 > {
2483 self.calls += 1;
2484 self.observed
2485 .push((creation.id(), creation.route(), creation.kind()));
2486 match self.plan {
2487 ChildPlan::CreateChild => {
2488 let id = creation.id();
2489 let kind = creation.kind();
2490 let (creation, _) = creation.into_parts();
2491 let (_, _child, _) = creation.into_parts();
2492 let (control, receiver) = std::sync::mpsc::channel();
2493 self.control_receivers.push(receiver);
2494 ItemSettlement::Accepted(ChildCreationOutcome::Established(
2495 CommittedChild::new(
2496 id,
2497 kind,
2498 EstablishedActor::issued(TestInstalled {
2499 endpoint: TestEndpoint(PhantomData),
2500 control,
2501 }),
2502 ),
2503 ))
2504 }
2505 ChildPlan::RejectBeforeTransfer => ItemSettlement::Rejected {
2506 item: creation,
2507 reason: CreationRejection::EnvironmentFailed,
2508 },
2509 }
2510 }
2511 }
2512
2513 fn host(plan: ChildPlan) -> RecordingHost {
2514 RecordingHost {
2515 calls: 0,
2516 observed: Vec::new(),
2517 plan,
2518 control_receivers: Vec::new(),
2519 }
2520 }
2521
2522 fn assert_send<T: Send>(_: &T) {}
2523
2524 #[test]
2525 fn empty_child_product_stages_no_creations() {
2526 let creations = <NoChildren as ChildProduct<TestAddr>>::stage(NoChildren);
2527 assert!(creations.is_empty());
2528 }
2529
2530 #[test]
2531 fn creation_values_preserve_ids_order_and_debug_identity() {
2532 let mut sequence = CreationSequence::new();
2533 let first = sequence.issue().expect("the first creation ID exists");
2534 let second = sequence.issue().expect("the second creation ID exists");
2535 assert_eq!(first.get(), 1);
2536 assert_eq!(second.get(), 2);
2537
2538 let first_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2539 let same_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2540 let second_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(second);
2541 assert_eq!(first_correlation, same_correlation);
2542 assert_ne!(first_correlation, second_correlation);
2543 assert_eq!(
2544 format!("{first_correlation:?}"),
2545 "CreationCorrelation(CreationId(1))"
2546 );
2547
2548 let mut creations = Creations::one(1_u8);
2549 creations.extend([2, 3]);
2550 assert_eq!(creations.len(), 3);
2551 assert!(!creations.is_empty());
2552 assert_eq!(creations.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
2553 let borrowed = (&creations).into_iter().copied().collect::<Vec<_>>();
2554 assert_eq!(borrowed, [1, 2, 3]);
2555
2556 let collected: Creations<_> = [4_u8, 5].into_iter().collect();
2557 assert_eq!(collected.len(), 2);
2558 let collected_values = collected.into_iter().collect::<Vec<_>>();
2559 assert_eq!(collected_values, [4, 5]);
2560
2561 let returned = ChildCreationSettled::<Child, ChildHead>::new(SettledItem::Unattempted(
2562 RoutedCreation::new(CreateChild::birth(first, Child), 17),
2563 ));
2564 assert_eq!(format!("{returned:?}"), "ChildCreationSettled { .. }");
2565 }
2566
2567 #[tokio::test]
2568 async fn concrete_child_dispatches_once_with_exact_creation_and_route() {
2569 let mut sequence = CreationSequence::new();
2570 let previous = sequence.issue().expect("the previous ID exists");
2571 let id = sequence.issue().expect("the replacement ID exists");
2572 let mut host = host(ChildPlan::CreateChild);
2573 let kind = CreationKind::replacement(previous);
2574 let future = Child.dispatch_birth(id, 17, kind, &mut host);
2575 assert_send(&future);
2576 let result = future.await;
2577
2578 let ItemSettlement::Accepted(ChildCreationOutcome::Established(established)) = result
2579 else {
2580 panic!("expected the child to be created");
2581 };
2582 assert_eq!(established.id(), id);
2583 assert_eq!(host.calls, 1);
2584 assert_eq!(host.observed, [(id, 17, kind)]);
2585 }
2586
2587 #[tokio::test]
2588 async fn concrete_child_returns_the_exact_rejected_creation_without_retry() {
2589 let mut sequence = CreationSequence::new();
2590 let previous = sequence.issue().expect("the previous ID exists");
2591 let id = sequence.issue().expect("the replacement ID exists");
2592 let mut host = host(ChildPlan::RejectBeforeTransfer);
2593 let kind = CreationKind::replacement(previous);
2594 let future = Child.dispatch_birth(id, 23, kind, &mut host);
2595 assert_send(&future);
2596 let result = future.await;
2597
2598 let ItemSettlement::Rejected { item, reason } = result else {
2599 panic!("expected refusal before child ownership transfer");
2600 };
2601 assert_eq!(
2602 item,
2603 RoutedCreation::new(CreateChild::replacement(id, previous, Child), 23)
2604 );
2605 assert_eq!(reason, CreationRejection::EnvironmentFailed);
2606 assert_eq!(host.calls, 1);
2607 assert_eq!(host.observed, [(id, 23, kind)]);
2608 }
2609
2610 #[tokio::test]
2611 async fn distinct_child_alternatives_preserve_one_canonical_protocol_identity() {
2612 type Alternatives = ChildChoice<Primary, ChildChoice<Fallback, Never>>;
2613
2614 fn requires_shared_protocol<C: Behavior<Protocol = SharedProtocol>>() {}
2615 requires_shared_protocol::<Primary>();
2616 requires_shared_protocol::<Fallback>();
2617
2618 let mut sequence = CreationSequence::new();
2619 let primary_id = sequence.issue().expect("the primary ID exists");
2620 let fallback_id = sequence.issue().expect("the fallback ID exists");
2621 let mut host = SharedProtocolHost::default();
2622 let primary = Alternatives::Head(Primary)
2623 .dispatch_birth(primary_id, 11, CreationKind::Birth, &mut host)
2624 .await;
2625 let fallback = Alternatives::Tail(ChildChoice::Head(Fallback))
2626 .dispatch_birth(fallback_id, 17, CreationKind::Birth, &mut host)
2627 .await;
2628
2629 let ItemSettlement::Accepted(ChildChoice::Head(ChildCreationOutcome::Established(primary))) =
2630 primary
2631 else {
2632 panic!("expected the primary child result");
2633 };
2634 assert_eq!(primary.id(), primary_id);
2635 let ItemSettlement::Accepted(ChildChoice::Tail(ChildChoice::Head(
2636 ChildCreationOutcome::Established(fallback),
2637 ))) = fallback
2638 else {
2639 panic!("expected the fallback child result");
2640 };
2641 assert_eq!(fallback.id(), fallback_id);
2642
2643 assert_eq!(
2644 host.0,
2645 [
2646 SharedCreation::Primary(primary_id, 11),
2647 SharedCreation::Fallback(fallback_id, 17),
2648 ]
2649 );
2650 }
2651
2652 #[test]
2653 fn birth_protocol_projection_recurses_without_inspecting_send_lanes() {
2654 type Protocols = <Primary as BirthProtocols>::Protocols;
2655 type Expected = BirthProtocol<SharedProtocol, BirthProtocol<Child, NoBirthProtocols>>;
2656
2657 trait Same<T> {}
2658 impl<T> Same<T> for T {}
2659 fn exact<T: Same<Expected>>() {}
2660 exact::<Protocols>();
2661 }
2662}