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 #[doc(hidden)]
25 #[must_use]
26 pub const fn get(self) -> u64 {
27 self.0.get()
28 }
29}
30
31#[derive(Debug, PartialEq, Eq)]
33pub struct CreationSequence {
34 next: Option<NonZeroU64>,
35}
36
37impl CreationSequence {
38 #[must_use]
40 pub const fn new() -> Self {
41 Self {
42 next: Some(NonZeroU64::MIN),
43 }
44 }
45
46 pub fn issue(&mut self) -> Option<CreationId> {
49 let value = self.next?;
50 self.next = value.checked_add(1);
51 Some(CreationId(value))
52 }
53}
54
55impl Default for CreationSequence {
56 fn default() -> Self {
57 Self::new()
58 }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub enum CreationKind {
64 Birth,
66 Replacement {
68 previous: CreationId,
70 },
71}
72
73impl CreationKind {
74 #[must_use]
75 pub const fn replacement(previous: CreationId) -> Self {
76 Self::Replacement { previous }
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
97pub struct CreateChild<A: Address, New> {
98 id: CreationId,
99 child: New,
100 kind: CreationKind,
101 address: PhantomData<fn() -> A>,
102}
103
104impl<A: Address, New> CreateChild<A, New> {
105 #[must_use]
106 pub(crate) const fn from_parts(id: CreationId, child: New, kind: CreationKind) -> Self {
107 Self {
108 id,
109 child,
110 kind,
111 address: PhantomData,
112 }
113 }
114
115 #[must_use]
116 pub const fn birth(id: CreationId, child: New) -> Self {
117 Self::from_parts(id, child, CreationKind::Birth)
118 }
119
120 #[must_use]
121 pub const fn replacement(id: CreationId, previous: CreationId, child: New) -> Self {
122 Self::from_parts(id, child, CreationKind::replacement(previous))
123 }
124
125 #[must_use]
126 pub const fn id(&self) -> CreationId {
127 self.id
128 }
129
130 #[must_use]
131 pub const fn kind(&self) -> CreationKind {
132 self.kind
133 }
134
135 #[must_use]
136 pub const fn child(&self) -> &New {
137 &self.child
138 }
139
140 #[doc(hidden)]
141 #[must_use]
142 pub fn into_parts(self) -> (CreationId, New, CreationKind) {
143 (self.id, self.child, self.kind)
144 }
145}
146
147#[derive(Debug, Clone, PartialEq, Eq)]
153pub struct Creations<Item> {
154 items: Vec<Item>,
155}
156
157impl<Item> Creations<Item> {
158 #[must_use]
160 pub const fn empty() -> Self {
161 Self { items: Vec::new() }
162 }
163
164 #[must_use]
165 pub fn one(item: Item) -> Self {
166 Self { items: vec![item] }
167 }
168
169 #[must_use]
170 pub fn and(mut self, item: Item) -> Self {
171 self.items.push(item);
172 self
173 }
174
175 #[must_use]
177 pub fn map<Mapped>(self, mut map: impl FnMut(Item) -> Mapped) -> Creations<Mapped> {
178 Creations::from_items(self.items.into_iter().map(&mut map).collect())
179 }
180
181 #[must_use]
182 pub fn len(&self) -> usize {
183 self.items.len()
184 }
185
186 #[must_use]
187 pub fn is_empty(&self) -> bool {
188 self.items.is_empty()
189 }
190
191 pub(crate) fn from_items(items: Vec<Item>) -> Self {
192 Self { items }
193 }
194
195 pub fn iter(&self) -> core::slice::Iter<'_, Item> {
196 self.items.iter()
197 }
198}
199
200impl<Item> Default for Creations<Item> {
201 fn default() -> Self {
202 Self::empty()
203 }
204}
205
206impl<Item> Extend<Item> for Creations<Item> {
207 fn extend<Items: IntoIterator<Item = Item>>(&mut self, items: Items) {
208 self.items.extend(items);
209 }
210}
211
212impl<Item> FromIterator<Item> for Creations<Item> {
213 fn from_iter<Items: IntoIterator<Item = Item>>(items: Items) -> Self {
214 Self::from_items(items.into_iter().collect())
215 }
216}
217
218impl<'a, Item> IntoIterator for &'a Creations<Item> {
219 type Item = &'a Item;
220 type IntoIter = core::slice::Iter<'a, Item>;
221
222 fn into_iter(self) -> Self::IntoIter {
223 self.iter()
224 }
225}
226
227impl<Item> IntoIterator for Creations<Item> {
228 type Item = Item;
229 type IntoIter = std::vec::IntoIter<Item>;
230
231 fn into_iter(self) -> Self::IntoIter {
232 self.items.into_iter()
233 }
234}
235
236pub trait ChildRole<Parent: Behavior> {
242 type Child: Behavior;
244
245 type Position: ChildPosition<<Parent::Birth as BirthMode>::Child, Self::Child>;
247}
248
249pub trait ChildOccurrence<Parent: Behavior>: Sized {
263 #[doc(hidden)]
265 type Resolution: ChildOccurrenceResolution<Parent, Self>;
266}
267
268#[doc(hidden)]
274pub struct DeclaredChildOccurrence;
275
276#[doc(hidden)]
280pub struct StructuralChildOccurrence<Position>(PhantomData<fn() -> Position>);
281
282pub trait ResolveChildOccurrence<Occurrence>:
360 Behavior + sealed::ResolveChildOccurrence<Occurrence>
361{
362 type Child: Behavior;
364
365 type Position: ChildPosition<<Self::Birth as BirthMode>::Child, Self::Child>;
367}
368
369impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
370where
371 Emitter: Behavior + BehaviorBase + sealed::ResolveChildOccurrence<Occurrence>,
372 Emitter::Base: Behavior,
373 Occurrence: ChildOccurrence<Emitter::Base>,
374 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
375{
376 type Child =
377 <Occurrence::Resolution as ResolveChildOccurrenceDescriptor<Emitter, Occurrence>>::Child;
378 type Position =
379 <Occurrence::Resolution as ResolveChildOccurrenceDescriptor<Emitter, Occurrence>>::Position;
380}
381
382pub type ResolvedChild<Emitter, Occurrence> =
384 <Emitter as ResolveChildOccurrence<Occurrence>>::Child;
385
386pub type ResolvedChildPosition<Emitter, Occurrence> =
389 <Emitter as ResolveChildOccurrence<Occurrence>>::Position;
390
391pub type RoleChild<Parent, Role> = <Role as ChildRole<Parent>>::Child;
393
394pub type RoleProtocol<Parent, Role> = <RoleChild<Parent, Role> as Behavior>::Protocol;
396
397#[doc(hidden)]
403#[derive(Debug, Clone, PartialEq, Eq)]
404pub struct RoutedCreation<A: Address, New> {
405 creation: CreateChild<A, New>,
406 route: A::Nonce,
407}
408
409impl<A: Address, New> RoutedCreation<A, New> {
410 #[must_use]
412 pub const fn new(creation: CreateChild<A, New>, route: A::Nonce) -> Self {
413 Self { creation, route }
414 }
415
416 #[must_use]
417 pub const fn id(&self) -> CreationId {
418 self.creation.id()
419 }
420
421 #[must_use]
422 pub const fn kind(&self) -> CreationKind {
423 self.creation.kind()
424 }
425
426 #[must_use]
427 pub const fn route(&self) -> A::Nonce {
428 self.route
429 }
430
431 #[must_use]
432 pub fn into_parts(self) -> (CreateChild<A, New>, A::Nonce) {
433 (self.creation, self.route)
434 }
435}
436
437#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
440pub enum AllocationRejection {
441 #[error("fresh actor-address allocation is exhausted")]
443 Exhausted,
444 #[error("the proposed actor address is already claimed")]
447 AddressAlreadyClaimed,
448}
449
450#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
452pub enum CreationRejection {
453 #[error("fresh allocation failed: {0}")]
455 Allocation(AllocationRejection),
456 #[error("child initialization failed")]
458 InitializationFailed,
459 #[error("the interpreter could not install and commit the child")]
461 EnvironmentFailed,
462}
463
464#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
466#[error("the creator child namespace is exhausted")]
467pub struct ChildNamespaceExhausted;
468
469impl<A, New> ActionItem for Creations<CreateChild<A, New>>
470where
471 A: Address,
472 A::Nonce: Send,
473 New: Send,
474{
475 type Accepted = Creations<RoutedCreation<A, New>>;
476 type Rejection = ChildNamespaceExhausted;
477 type Prerequisite = Never;
478}
479
480pub enum EstablishedCreation<P, Occurrence>
525where
526 P: Protocol,
527 P::Addr: EndpointAddress,
528{
529 Installed {
530 id: CreationId,
531 kind: CreationKind,
532 recipient: EstablishedRecipient<P>,
533 occurrence: PhantomData<fn() -> Occurrence>,
534 },
535 Rejected {
536 id: CreationId,
537 kind: CreationKind,
538 reason: CreationRejection,
539 occurrence: PhantomData<fn() -> Occurrence>,
540 },
541}
542
543impl<P, Occurrence> EstablishedCreation<P, Occurrence>
544where
545 P: Protocol,
546 P::Addr: EndpointAddress,
547{
548 #[must_use]
549 pub const fn installed(
550 id: CreationId,
551 kind: CreationKind,
552 recipient: EstablishedRecipient<P>,
553 ) -> Self {
554 Self::Installed {
555 id,
556 kind,
557 recipient,
558 occurrence: PhantomData,
559 }
560 }
561
562 #[must_use]
563 pub const fn rejected(id: CreationId, kind: CreationKind, reason: CreationRejection) -> Self {
564 Self::Rejected {
565 id,
566 kind,
567 reason,
568 occurrence: PhantomData,
569 }
570 }
571
572 #[must_use]
573 pub const fn id(&self) -> CreationId {
574 match self {
575 Self::Installed { id, .. } | Self::Rejected { id, .. } => *id,
576 }
577 }
578
579 #[must_use]
580 pub const fn kind(&self) -> CreationKind {
581 match self {
582 Self::Installed { kind, .. } | Self::Rejected { kind, .. } => *kind,
583 }
584 }
585
586 pub fn into_recipient(self) -> Result<EstablishedRecipient<P>, CreationRejection> {
592 match self {
593 Self::Installed { recipient, .. } => Ok(recipient),
594 Self::Rejected { reason, .. } => Err(reason),
595 }
596 }
597
598 pub fn into_actor<Parent>(
610 self,
611 ) -> Result<EstablishedActor<RoleChild<Parent, Occurrence>>, CreationRejection>
612 where
613 Parent: Behavior,
614 Occurrence: ChildRole<Parent>,
615 RoleChild<Parent, Occurrence>: Behavior<Protocol = P>,
616 {
617 self.into_recipient().map(EstablishedActor::from_recipient)
618 }
619}
620
621pub enum ChildCreationOutcome<C, Occurrence>
629where
630 C: Behavior,
631 BehaviorAddr<C>: EndpointAddress,
632{
633 Established {
635 established: EstablishedCreation<C::Protocol, Occurrence>,
637 },
638 InitializationRejected {
640 creation: RoutedCreation<BehaviorAddr<C>, C>,
642 error: C::Error,
644 },
645 HostRejected {
647 creation: RoutedCreation<BehaviorAddr<C>, C>,
649 initialization: Actions<BehaviorAddr<C>, C::Ph, C::Sends, C::Birth>,
651 reason: CreationRejection,
653 },
654}
655
656impl<C, Occurrence> ChildCreationOutcome<C, Occurrence>
657where
658 C: Behavior,
659 BehaviorAddr<C>: EndpointAddress,
660{
661 pub fn into_actor(self) -> Result<EstablishedActor<C>, Self> {
673 match self {
674 Self::Established {
675 established: EstablishedCreation::Installed { recipient, .. },
676 } => Ok(EstablishedActor::from_recipient(recipient)),
677 other => Err(other),
678 }
679 }
680}
681
682#[must_use = "a child-creation settlement must be admitted or retained"]
690pub struct ChildCreationSettled<C, Occurrence>
691where
692 C: Behavior,
693 BehaviorAddr<C>: EndpointAddress,
694{
695 settlement: SettledItem<
696 RoutedCreation<BehaviorAddr<C>, C>,
697 ItemSettlement<
698 RoutedCreation<BehaviorAddr<C>, C>,
699 ChildCreationOutcome<C, Occurrence>,
700 CreationRejection,
701 Never,
702 >,
703 >,
704}
705
706impl<C, Occurrence> ChildCreationSettled<C, Occurrence>
707where
708 C: Behavior,
709 BehaviorAddr<C>: EndpointAddress,
710{
711 #[must_use]
712 pub const fn new(
713 settlement: SettledItem<
714 RoutedCreation<BehaviorAddr<C>, C>,
715 ItemSettlement<
716 RoutedCreation<BehaviorAddr<C>, C>,
717 ChildCreationOutcome<C, Occurrence>,
718 CreationRejection,
719 Never,
720 >,
721 >,
722 ) -> Self {
723 Self { settlement }
724 }
725
726 #[must_use]
728 pub fn into_settlement(
729 self,
730 ) -> SettledItem<
731 RoutedCreation<BehaviorAddr<C>, C>,
732 ItemSettlement<
733 RoutedCreation<BehaviorAddr<C>, C>,
734 ChildCreationOutcome<C, Occurrence>,
735 CreationRejection,
736 Never,
737 >,
738 > {
739 self.settlement
740 }
741}
742
743impl<C, Occurrence> core::fmt::Debug for ChildCreationSettled<C, Occurrence>
744where
745 C: Behavior,
746 BehaviorAddr<C>: EndpointAddress,
747{
748 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
749 formatter
750 .debug_struct("ChildCreationSettled")
751 .finish_non_exhaustive()
752 }
753}
754
755#[doc(hidden)]
778pub struct CreationCorrelation<P, Occurrence>
779where
780 P: Protocol,
781{
782 id: CreationId,
783 occurrence: PhantomData<fn() -> (P, Occurrence)>,
784}
785
786impl<P, Occurrence> CreationCorrelation<P, Occurrence>
787where
788 P: Protocol,
789{
790 #[must_use]
791 pub const fn new(id: CreationId) -> Self {
792 Self {
793 id,
794 occurrence: PhantomData,
795 }
796 }
797
798 #[must_use]
799 pub const fn id(self) -> CreationId {
800 self.id
801 }
802}
803
804impl<P, Occurrence> Copy for CreationCorrelation<P, Occurrence> where P: Protocol {}
805
806impl<P, Occurrence> Clone for CreationCorrelation<P, Occurrence>
807where
808 P: Protocol,
809{
810 fn clone(&self) -> Self {
811 *self
812 }
813}
814
815impl<P, Occurrence> core::fmt::Debug for CreationCorrelation<P, Occurrence>
816where
817 P: Protocol,
818{
819 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
820 formatter
821 .debug_tuple("CreationCorrelation")
822 .field(&self.id)
823 .finish()
824 }
825}
826
827impl<P, Occurrence> PartialEq for CreationCorrelation<P, Occurrence>
828where
829 P: Protocol,
830{
831 fn eq(&self, other: &Self) -> bool {
832 self.id == other.id
833 }
834}
835
836impl<P, Occurrence> Eq for CreationCorrelation<P, Occurrence> where P: Protocol {}
837
838pub struct ChildDelivery<P, Occurrence>
845where
846 P: Protocol,
847{
848 pub creation: CreationId,
849 pub message: P::Msg,
850 occurrence: PhantomData<fn() -> Occurrence>,
851}
852
853pub struct ChildInput<Child, Source, Input, Occurrence>
866where
867 Child: Behavior,
868{
869 pub creation: CreationId,
871 pub input: Input,
873 marker: PhantomData<fn() -> (Child, Source, Occurrence)>,
874}
875
876#[derive(Clone, Copy, Debug, Eq, PartialEq)]
878pub enum ChildDeliveryReason {
879 MissingBinding,
880 ClosedRecipient,
881}
882
883#[derive(Clone, Copy, Debug, Eq, PartialEq)]
885pub enum ChildInputReason {
886 MissingBinding,
887 ClosedControlLane,
888}
889
890#[derive(Debug, Clone, Copy, PartialEq, Eq)]
897pub struct ChildReport<R> {
898 pub child: CreationId,
900 pub report: R,
902}
903
904impl<R> ChildReport<R> {
905 #[must_use]
907 pub const fn new(child: CreationId, report: R) -> Self {
908 Self { child, report }
909 }
910}
911
912impl<R> From<(CreationId, crate::ReportToParent<R>)> for ChildReport<R> {
913 fn from((child, request): (CreationId, crate::ReportToParent<R>)) -> Self {
914 Self::new(child, request.into_inner())
915 }
916}
917
918impl<Child, Source, Input, Occurrence> ChildInput<Child, Source, Input, Occurrence>
919where
920 Child: Behavior,
921 Child::Event: crate::ChildInputIngress<Source, Input>,
922{
923 #[must_use]
925 pub const fn after(creation: CreationId, input: Input) -> Self {
926 Self {
927 creation,
928 input,
929 marker: PhantomData,
930 }
931 }
932}
933
934impl<Child, Source, Input, Occurrence> Clone for ChildInput<Child, Source, Input, Occurrence>
935where
936 Child: Behavior,
937 Input: Clone,
938{
939 fn clone(&self) -> Self {
940 Self {
941 creation: self.creation,
942 input: self.input.clone(),
943 marker: PhantomData,
944 }
945 }
946}
947
948impl<P, Occurrence> ChildDelivery<P, Occurrence>
949where
950 P: Protocol,
951{
952 #[must_use]
953 pub const fn after(creation: CreationId, message: P::Msg) -> Self {
954 Self {
955 creation,
956 message,
957 occurrence: PhantomData,
958 }
959 }
960}
961
962impl<P, Occurrence> Clone for ChildDelivery<P, Occurrence>
963where
964 P: Protocol,
965 P::Msg: Clone,
966{
967 fn clone(&self) -> Self {
968 Self {
969 creation: self.creation,
970 message: self.message.clone(),
971 occurrence: PhantomData,
972 }
973 }
974}
975
976impl<P, Occurrence> ActionItem for ChildDelivery<P, Occurrence>
977where
978 P: Protocol,
979 P::Msg: Send,
980{
981 type Accepted = ();
982 type Rejection = ChildDeliveryReason;
983 type Prerequisite = CreationCorrelation<P, Occurrence>;
984}
985
986impl<Child, Source, Input, Occurrence> ActionItem for ChildInput<Child, Source, Input, Occurrence>
987where
988 Child: Behavior,
989 Input: Send,
990{
991 type Accepted = ();
992 type Rejection = ChildInputReason;
993 type Prerequisite = CreationCorrelation<Child::Protocol, Occurrence>;
994}
995
996pub trait EstablishChild<Occurrence, C>
1052where
1053 C: Behavior,
1054 BehaviorAddr<C>: EndpointAddress,
1055{
1056 fn establish_child(
1058 &mut self,
1059 creation: RoutedCreation<BehaviorAddr<C>, C>,
1060 ) -> impl Future<
1061 Output = ItemSettlement<
1062 RoutedCreation<BehaviorAddr<C>, C>,
1063 ChildCreationOutcome<C, Occurrence>,
1064 CreationRejection,
1065 Never,
1066 >,
1067 > + Send;
1068}
1069
1070#[doc(hidden)]
1075pub trait ChildCreationProduct<A: Address, Occurrence>: Sized {
1076 type Result;
1077}
1078
1079pub trait DispatchBirth<A: Address, Host>: ChildCreationProduct<A, ChildHead> + Sized {
1088 fn dispatch_birth(
1091 self,
1092 id: CreationId,
1093 route: A::Nonce,
1094 kind: CreationKind,
1095 host: &mut Host,
1096 ) -> impl Future<
1097 Output = ItemSettlement<
1098 RoutedCreation<A, Self>,
1099 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1100 CreationRejection,
1101 Never,
1102 >,
1103 > + Send;
1104}
1105
1106trait CreateSelectedChild<A: Address, Occurrence, Host>:
1107 ChildCreationProduct<A, Occurrence> + Sized
1108{
1109 fn dispatch_birth_at(
1110 self,
1111 id: CreationId,
1112 route: A::Nonce,
1113 kind: CreationKind,
1114 host: &mut Host,
1115 ) -> impl Future<
1116 Output = ItemSettlement<
1117 RoutedCreation<A, Self>,
1118 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1119 CreationRejection,
1120 Never,
1121 >,
1122 > + Send;
1123}
1124
1125impl<A, Child, Host> DispatchBirth<A, Host> for Child
1126where
1127 A: Address,
1128 Child: CreateSelectedChild<A, ChildHead, Host>,
1129{
1130 fn dispatch_birth(
1131 self,
1132 id: CreationId,
1133 route: A::Nonce,
1134 kind: CreationKind,
1135 host: &mut Host,
1136 ) -> impl Future<
1137 Output = ItemSettlement<
1138 RoutedCreation<A, Self>,
1139 <Self as ChildCreationProduct<A, ChildHead>>::Result,
1140 CreationRejection,
1141 Never,
1142 >,
1143 > + Send {
1144 self.dispatch_birth_at(id, route, kind, host)
1145 }
1146}
1147
1148#[derive(Debug, Clone, PartialEq, Eq)]
1222pub enum ChildChoice<Head, Tail> {
1223 Head(Head),
1225 Tail(Tail),
1227}
1228
1229#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1231pub struct ChildHead;
1232
1233#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1235pub struct ChildTail<Position>(PhantomData<fn() -> Position>);
1236
1237pub trait ChildPosition<Children, Child: Behavior>: sealed::ChildPosition {}
1294
1295impl sealed::ChildPosition for ChildHead {}
1296
1297impl<Child: Behavior> ChildPosition<Child, Child> for ChildHead {}
1298
1299impl<Head: Behavior, Tail> ChildPosition<ChildChoice<Head, Tail>, Head> for ChildHead {}
1300
1301impl<Position> sealed::ChildPosition for ChildTail<Position> {}
1302
1303impl<Head, Tail, Position, Child> ChildPosition<ChildChoice<Head, Tail>, Child>
1304 for ChildTail<Position>
1305where
1306 Child: Behavior,
1307 Position: ChildPosition<Tail, Child>,
1308{
1309}
1310
1311pub trait BirthNodeAppend<Tail>: sealed::BirthNode + Sized
1336where
1337 Tail: sealed::BirthNode,
1338{
1339 type Output: sealed::BirthNode;
1342
1343 fn append_prefix(self) -> Self::Output;
1346
1347 fn append_tail(tail: Tail) -> Self::Output;
1349
1350 #[must_use]
1352 fn append_creations<A: Address>(
1353 prefix: Creations<CreateChild<A, Self>>,
1354 tail: Creations<CreateChild<A, Tail>>,
1355 ) -> Creations<CreateChild<A, Self::Output>> {
1356 let mut combined = Vec::with_capacity(prefix.len() + tail.len());
1357 combined.extend(prefix.into_iter().map(|creation| {
1358 let (id, child, kind) = creation.into_parts();
1359 CreateChild::from_parts(id, Self::append_prefix(child), kind)
1360 }));
1361 combined.extend(tail.into_iter().map(|creation| {
1362 let (id, child, kind) = creation.into_parts();
1363 CreateChild::from_parts(id, Self::append_tail(child), kind)
1364 }));
1365 Creations::from_items(combined)
1366 }
1367}
1368
1369impl<Tail> BirthNodeAppend<Tail> for Never
1370where
1371 Tail: sealed::BirthNode,
1372{
1373 type Output = Tail;
1374
1375 fn append_prefix(self) -> Self::Output {
1376 match self {}
1377 }
1378
1379 fn append_tail(tail: Tail) -> Self::Output {
1380 tail
1381 }
1382}
1383
1384impl<Node> BirthNodeAppend<Never> for Node
1385where
1386 Node: sealed::NonEmptyBirthNode,
1387{
1388 type Output = Node;
1389
1390 fn append_prefix(self) -> Self::Output {
1391 self
1392 }
1393
1394 fn append_tail(tail: Never) -> Self::Output {
1395 match tail {}
1396 }
1397}
1398
1399impl<Child, Tail> BirthNodeAppend<Tail> for Child
1400where
1401 Child: Behavior,
1402 Tail: sealed::NonEmptyBirthNode,
1403{
1404 type Output = ChildChoice<Child, Tail>;
1405
1406 fn append_prefix(self) -> Self::Output {
1407 ChildChoice::Head(self)
1408 }
1409
1410 fn append_tail(tail: Tail) -> Self::Output {
1411 ChildChoice::Tail(tail)
1412 }
1413}
1414
1415impl<Head, Rest, Tail> BirthNodeAppend<Tail> for ChildChoice<Head, Rest>
1416where
1417 Head: Behavior,
1418 Rest: sealed::BirthNode + BirthNodeAppend<Tail>,
1419 Tail: sealed::NonEmptyBirthNode,
1420 Rest::Output: sealed::BirthNode,
1421{
1422 type Output = ChildChoice<Head, Rest::Output>;
1423
1424 fn append_prefix(self) -> Self::Output {
1425 match self {
1426 ChildChoice::Head(head) => ChildChoice::Head(head),
1427 ChildChoice::Tail(rest) => ChildChoice::Tail(rest.append_prefix()),
1428 }
1429 }
1430
1431 fn append_tail(tail: Tail) -> Self::Output {
1432 ChildChoice::Tail(Rest::append_tail(tail))
1433 }
1434}
1435
1436impl<Parent: Behavior> ChildOccurrence<Parent> for ChildHead {
1437 type Resolution = StructuralChildOccurrence<Self>;
1438}
1439
1440impl<Parent: Behavior, Position> ChildOccurrence<Parent> for ChildTail<Position> {
1441 type Resolution = StructuralChildOccurrence<Self>;
1442}
1443
1444#[doc(hidden)]
1451pub trait ChildOccurrenceResolution<Parent: Behavior, Occurrence>:
1452 sealed::ChildOccurrenceDescriptor + sealed::OccurrenceResolution<Parent, Occurrence>
1453{
1454}
1455
1456impl<Parent, Occurrence> ChildOccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1457where
1458 Parent: Behavior,
1459 Occurrence: ChildRole<Parent>,
1460{
1461}
1462
1463impl<Parent: Behavior> ChildOccurrenceResolution<Parent, ChildHead>
1464 for StructuralChildOccurrence<ChildHead>
1465{
1466}
1467
1468impl<Parent: Behavior, Position> ChildOccurrenceResolution<Parent, ChildTail<Position>>
1469 for StructuralChildOccurrence<ChildTail<Position>>
1470{
1471}
1472
1473#[doc(hidden)]
1475pub trait ResolveChildOccurrenceDescriptor<Emitter: Behavior, Occurrence>:
1476 sealed::ChildOccurrenceDescriptor + sealed::ResolveDescriptor<Emitter, Occurrence>
1477{
1478 type Child: Behavior;
1479 type Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Self::Child>;
1480}
1481
1482impl<Emitter, Occurrence, Position> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1483 for StructuralChildOccurrence<Position>
1484where
1485 Emitter: Behavior,
1486 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1487 Position: ChildPosition<
1488 <Emitter::Birth as BirthMode>::Child,
1489 <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child,
1490 >,
1491{
1492 type Child = <<Emitter::Birth as BirthMode>::Child as BirthNodeAt<Position>>::Child;
1493 type Position = Position;
1494}
1495
1496impl<Emitter, Occurrence> ResolveChildOccurrenceDescriptor<Emitter, Occurrence>
1497 for DeclaredChildOccurrence
1498where
1499 Emitter:
1500 Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol> + BehaviorBase,
1501 Emitter::Base: Behavior,
1502 Occurrence: ChildRole<Emitter::Base>,
1503 <Emitter::Birth as BirthMode>::Child:
1504 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1505 Occurrence::Position: ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1506{
1507 type Child = Occurrence::Child;
1508 type Position = Occurrence::Position;
1509}
1510
1511#[doc(hidden)]
1513pub trait BirthNodeAt<Position>: sealed::BirthNode {
1514 type Child: Behavior;
1515}
1516
1517impl<Child: Behavior> BirthNodeAt<ChildHead> for Child {
1518 type Child = Child;
1519}
1520
1521impl<Head: Behavior, Tail> BirthNodeAt<ChildHead> for ChildChoice<Head, Tail>
1522where
1523 Tail: sealed::BirthNode,
1524{
1525 type Child = Head;
1526}
1527
1528impl<Head, Tail, Position> BirthNodeAt<ChildTail<Position>> for ChildChoice<Head, Tail>
1529where
1530 Head: Behavior,
1531 Tail: BirthNodeAt<Position>,
1532{
1533 type Child = <Tail as BirthNodeAt<Position>>::Child;
1534}
1535
1536pub trait ChildOccurrenceShape {
1566 type Empty;
1568
1569 type Member<Occurrence, Child: Behavior, Tail>;
1571}
1572
1573pub trait ChildOccurrenceProduct<Shape>: sealed::BirthNode
1602where
1603 Shape: ChildOccurrenceShape,
1604{
1605 type Product;
1607}
1608
1609#[doc(hidden)]
1612pub trait ChildOccurrenceProductAt<Occurrence, Shape>: sealed::BirthNode
1613where
1614 Shape: ChildOccurrenceShape,
1615{
1616 type Product;
1617}
1618
1619impl<Node, Shape> ChildOccurrenceProduct<Shape> for Node
1620where
1621 Node: ChildOccurrenceProductAt<ChildHead, Shape>,
1622 Shape: ChildOccurrenceShape,
1623{
1624 type Product = <Node as ChildOccurrenceProductAt<ChildHead, Shape>>::Product;
1625}
1626
1627impl<Occurrence, Shape, Child> ChildOccurrenceProductAt<Occurrence, Shape> for Child
1628where
1629 Shape: ChildOccurrenceShape,
1630 Child: Behavior,
1631{
1632 type Product = Shape::Member<Occurrence, Child, Shape::Empty>;
1633}
1634
1635impl<Occurrence, Shape, Head, Tail> ChildOccurrenceProductAt<Occurrence, Shape>
1636 for ChildChoice<Head, Tail>
1637where
1638 Shape: ChildOccurrenceShape,
1639 Head: Behavior,
1640 Tail: ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>,
1641{
1642 type Product = Shape::Member<
1643 Occurrence,
1644 Head,
1645 <Tail as ChildOccurrenceProductAt<ChildTail<Occurrence>, Shape>>::Product,
1646 >;
1647}
1648
1649impl<Occurrence, Shape> ChildOccurrenceProductAt<Occurrence, Shape> for Never
1650where
1651 Shape: ChildOccurrenceShape,
1652{
1653 type Product = Shape::Empty;
1654}
1655
1656pub type ChildOccurrences<Node, Shape> = <Node as ChildOccurrenceProduct<Shape>>::Product;
1658
1659mod sealed {
1660 use super::{
1661 Behavior, BehaviorBase, BirthMode, BirthNodeAt, ChildChoice, ChildHead, ChildOccurrence,
1662 ChildRole, ChildTail, DeclaredChildOccurrence, Never, ResolveChildOccurrenceDescriptor,
1663 StructuralChildOccurrence,
1664 };
1665
1666 pub trait BirthNode {}
1667
1668 pub trait NonEmptyBirthNode: BirthNode {}
1669
1670 impl<Child: Behavior> BirthNode for Child {}
1671 impl<Child: Behavior> NonEmptyBirthNode for Child {}
1672
1673 impl<Head, Tail> BirthNode for ChildChoice<Head, Tail>
1674 where
1675 Head: Behavior,
1676 Tail: BirthNode,
1677 {
1678 }
1679
1680 impl<Head, Tail> NonEmptyBirthNode for ChildChoice<Head, Tail>
1681 where
1682 Head: Behavior,
1683 Tail: BirthNode,
1684 {
1685 }
1686
1687 impl BirthNode for Never {}
1688
1689 pub trait ChildPosition {}
1690 pub trait ChildProduct {}
1691
1692 pub trait ChildOccurrenceDescriptor {}
1693
1694 impl ChildOccurrenceDescriptor for DeclaredChildOccurrence {}
1695
1696 impl<Position> ChildOccurrenceDescriptor for StructuralChildOccurrence<Position> {}
1697
1698 pub trait OccurrenceResolution<Parent: Behavior, Occurrence> {}
1699
1700 impl<Parent, Occurrence> OccurrenceResolution<Parent, Occurrence> for DeclaredChildOccurrence
1701 where
1702 Parent: Behavior,
1703 Occurrence: ChildRole<Parent>,
1704 {
1705 }
1706
1707 impl<Parent: Behavior> OccurrenceResolution<Parent, ChildHead>
1708 for StructuralChildOccurrence<ChildHead>
1709 {
1710 }
1711
1712 impl<Parent: Behavior, Position> OccurrenceResolution<Parent, ChildTail<Position>>
1713 for StructuralChildOccurrence<ChildTail<Position>>
1714 {
1715 }
1716
1717 pub trait ResolveDescriptor<Emitter: Behavior, Occurrence> {}
1718
1719 impl<Emitter, Occurrence, Position> ResolveDescriptor<Emitter, Occurrence>
1720 for StructuralChildOccurrence<Position>
1721 where
1722 Emitter: Behavior,
1723 <Emitter::Birth as BirthMode>::Child: BirthNodeAt<Position>,
1724 {
1725 }
1726
1727 impl<Emitter, Occurrence> ResolveDescriptor<Emitter, Occurrence> for DeclaredChildOccurrence
1728 where
1729 Emitter: Behavior<Protocol = <<Emitter as BehaviorBase>::Base as Behavior>::Protocol>
1730 + BehaviorBase,
1731 Emitter::Base: Behavior,
1732 Occurrence: ChildRole<Emitter::Base>,
1733 <Emitter::Birth as BirthMode>::Child:
1734 BirthNodeAt<Occurrence::Position, Child = Occurrence::Child>,
1735 Occurrence::Position:
1736 super::ChildPosition<<Emitter::Birth as BirthMode>::Child, Occurrence::Child>,
1737 {
1738 }
1739
1740 pub trait ResolveChildOccurrence<Occurrence> {}
1741
1742 impl<Emitter, Occurrence> ResolveChildOccurrence<Occurrence> for Emitter
1743 where
1744 Emitter: Behavior + BehaviorBase,
1745 Emitter::Base: Behavior,
1746 Occurrence: ChildOccurrence<Emitter::Base>,
1747 Occurrence::Resolution: ResolveChildOccurrenceDescriptor<Emitter, Occurrence>,
1748 {
1749 }
1750}
1751
1752#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1754pub struct NoChildren;
1755
1756impl sealed::ChildProduct for NoChildren {}
1757
1758pub struct ChildCons<A: Address, C, Earlier> {
1760 creation: CreateChild<A, C>,
1761 earlier: Earlier,
1762}
1763
1764impl<A: Address, C, Earlier> sealed::ChildProduct for ChildCons<A, C, Earlier> {}
1765
1766pub struct Children<A: Address, Product = NoChildren> {
1772 product: Product,
1773 address: PhantomData<fn() -> A>,
1774}
1775
1776pub trait ChildProduct<A: Address>: sealed::ChildProduct + Sized {
1778 type Choice: BirthNodeAppend<Never>;
1780
1781 #[doc(hidden)]
1782 fn stage(self) -> Vec<CreateChild<A, Self::Choice>>;
1783}
1784
1785impl<A: Address> ChildProduct<A> for NoChildren {
1786 type Choice = Never;
1787
1788 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1789 Vec::new()
1790 }
1791}
1792
1793impl<A, C, Earlier> ChildProduct<A> for ChildCons<A, C, Earlier>
1794where
1795 A: Address,
1796 C: Behavior,
1797 C::Protocol: Protocol<Addr = A>,
1798 Earlier: ChildProduct<A>,
1799{
1800 type Choice = ChildChoice<C, Earlier::Choice>;
1801
1802 fn stage(self) -> Vec<CreateChild<A, Self::Choice>> {
1803 let earlier = self.earlier.stage();
1804 let mut creates = earlier
1805 .into_iter()
1806 .map(|creation| {
1807 let (id, child, kind) = creation.into_parts();
1808 CreateChild::from_parts(id, ChildChoice::Tail(child), kind)
1809 })
1810 .collect::<Vec<_>>();
1811 let (id, child, kind) = self.creation.into_parts();
1812 creates.push(CreateChild::from_parts(id, ChildChoice::Head(child), kind));
1813 creates
1814 }
1815}
1816
1817impl<A: Address> Children<A, NoChildren> {
1818 #[must_use]
1820 pub const fn new() -> Self {
1821 Self {
1822 product: NoChildren,
1823 address: PhantomData,
1824 }
1825 }
1826}
1827
1828impl<A: Address> Default for Children<A, NoChildren> {
1829 fn default() -> Self {
1830 Self::new()
1831 }
1832}
1833
1834impl<A: Address, Product> Children<A, Product> {
1835 #[must_use]
1837 pub fn create<C>(self, creation: CreateChild<A, C>) -> Children<A, ChildCons<A, C, Product>>
1838 where
1839 C: Behavior,
1840 C::Protocol: Protocol<Addr = A>,
1841 {
1842 Children {
1843 product: ChildCons {
1844 creation,
1845 earlier: self.product,
1846 },
1847 address: PhantomData,
1848 }
1849 }
1850
1851 #[must_use]
1853 pub fn child<C>(self, id: CreationId, child: C) -> Children<A, ChildCons<A, C, Product>>
1854 where
1855 C: Behavior,
1856 C::Protocol: Protocol<Addr = A>,
1857 {
1858 self.create(CreateChild::birth(id, child))
1859 }
1860}
1861
1862impl<A, Product> Children<A, Product>
1863where
1864 A: Address,
1865 Product: ChildProduct<A>,
1866{
1867 #[must_use]
1869 pub fn into_creates(self) -> Creations<CreateChild<A, Product::Choice>> {
1870 Creations::from_items(self.product.stage())
1871 }
1872}
1873
1874impl<A, Occurrence, Head, Tail> ChildCreationProduct<A, Occurrence> for ChildChoice<Head, Tail>
1875where
1876 A: EndpointAddress,
1877 Head: Behavior,
1878 Head::Protocol: Protocol<Addr = A>,
1879 Tail: ChildCreationProduct<A, ChildTail<Occurrence>>,
1880{
1881 type Result = ChildChoice<
1882 ChildCreationOutcome<Head, Occurrence>,
1883 <Tail as ChildCreationProduct<A, ChildTail<Occurrence>>>::Result,
1884 >;
1885}
1886
1887impl<A, Occurrence, Head, Tail, Host> CreateSelectedChild<A, Occurrence, Host>
1888 for ChildChoice<Head, Tail>
1889where
1890 A: EndpointAddress,
1891 A::Nonce: Send,
1892 Head: Behavior + Send,
1893 Head::Protocol: Protocol<Addr = A>,
1894 Tail: CreateSelectedChild<A, ChildTail<Occurrence>, Host> + Send,
1895 Host: EstablishChild<Occurrence, Head> + Send,
1896{
1897 async fn dispatch_birth_at(
1898 self,
1899 id: CreationId,
1900 route: A::Nonce,
1901 kind: CreationKind,
1902 host: &mut Host,
1903 ) -> ItemSettlement<
1904 RoutedCreation<A, Self>,
1905 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1906 CreationRejection,
1907 Never,
1908 > {
1909 match self {
1910 Self::Head(child) => {
1911 let creation = RoutedCreation::new(CreateChild::from_parts(id, child, kind), route);
1912 match host.establish_child(creation).await {
1913 ItemSettlement::Accepted(receipt) => {
1914 ItemSettlement::Accepted(ChildChoice::Head(receipt))
1915 }
1916 ItemSettlement::Rejected { item, reason } => {
1917 let (creation, route) = item.into_parts();
1918 let (id, child, kind) = creation.into_parts();
1919 ItemSettlement::Rejected {
1920 item: RoutedCreation::new(
1921 CreateChild::from_parts(id, Self::Head(child), kind),
1922 route,
1923 ),
1924 reason,
1925 }
1926 }
1927 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
1928 ItemSettlement::Corrupt { item, fault } => {
1929 let (creation, route) = item.into_parts();
1930 let (id, child, kind) = creation.into_parts();
1931 ItemSettlement::Corrupt {
1932 item: RoutedCreation::new(
1933 CreateChild::from_parts(id, Self::Head(child), kind),
1934 route,
1935 ),
1936 fault,
1937 }
1938 }
1939 }
1940 }
1941 Self::Tail(tail) => match tail.dispatch_birth_at(id, route, kind, host).await {
1942 ItemSettlement::Accepted(receipt) => {
1943 ItemSettlement::Accepted(ChildChoice::Tail(receipt))
1944 }
1945 ItemSettlement::Rejected { item, reason } => {
1946 let (creation, route) = item.into_parts();
1947 let (id, child, kind) = creation.into_parts();
1948 ItemSettlement::Rejected {
1949 item: RoutedCreation::new(
1950 CreateChild::from_parts(id, Self::Tail(child), kind),
1951 route,
1952 ),
1953 reason,
1954 }
1955 }
1956 ItemSettlement::Blocked { prerequisite, .. } => match prerequisite {},
1957 ItemSettlement::Corrupt { item, fault } => {
1958 let (creation, route) = item.into_parts();
1959 let (id, child, kind) = creation.into_parts();
1960 ItemSettlement::Corrupt {
1961 item: RoutedCreation::new(
1962 CreateChild::from_parts(id, Self::Tail(child), kind),
1963 route,
1964 ),
1965 fault,
1966 }
1967 }
1968 },
1969 }
1970 }
1971}
1972
1973impl<A, Occurrence> ChildCreationProduct<A, Occurrence> for Never
1974where
1975 A: Address,
1976{
1977 type Result = Never;
1978}
1979
1980impl<A, Occurrence, Host> CreateSelectedChild<A, Occurrence, Host> for Never
1981where
1982 A: Address,
1983{
1984 fn dispatch_birth_at(
1985 self,
1986 _id: CreationId,
1987 _route: A::Nonce,
1988 _kind: CreationKind,
1989 _host: &mut Host,
1990 ) -> impl Future<
1991 Output = ItemSettlement<
1992 RoutedCreation<A, Self>,
1993 <Self as ChildCreationProduct<A, Occurrence>>::Result,
1994 CreationRejection,
1995 Never,
1996 >,
1997 > + Send {
1998 async move { match self {} }
1999 }
2000}
2001
2002impl<A, Occurrence, C> ChildCreationProduct<A, Occurrence> for C
2003where
2004 A: EndpointAddress,
2005 C: Behavior,
2006 C::Protocol: Protocol<Addr = A>,
2007{
2008 type Result = ChildCreationOutcome<C, Occurrence>;
2009}
2010
2011impl<A, Occurrence, C, Host> CreateSelectedChild<A, Occurrence, Host> for C
2012where
2013 A: EndpointAddress,
2014 C: Behavior,
2015 C::Protocol: Protocol<Addr = A>,
2016 Host: EstablishChild<Occurrence, C>,
2017{
2018 fn dispatch_birth_at(
2019 self,
2020 id: CreationId,
2021 route: A::Nonce,
2022 kind: CreationKind,
2023 host: &mut Host,
2024 ) -> impl Future<
2025 Output = ItemSettlement<
2026 RoutedCreation<A, Self>,
2027 <Self as ChildCreationProduct<A, Occurrence>>::Result,
2028 CreationRejection,
2029 Never,
2030 >,
2031 > + Send {
2032 host.establish_child(RoutedCreation::new(
2033 CreateChild::from_parts(id, self, kind),
2034 route,
2035 ))
2036 }
2037}
2038
2039pub trait BirthMode {
2041 type Child;
2042}
2043
2044pub struct NoBirthProtocols;
2046
2047pub struct BirthProtocol<P: Protocol, Tail> {
2049 protocol: PhantomData<fn() -> P>,
2050 tail: PhantomData<fn() -> Tail>,
2051}
2052
2053pub struct BirthProtocolHead;
2055
2056pub struct BirthProtocolTail<Position>(PhantomData<fn() -> Position>);
2058
2059pub trait BirthProtocolAt<P: Protocol, Position> {}
2061
2062impl<P: Protocol, Tail> BirthProtocolAt<P, BirthProtocolHead> for BirthProtocol<P, Tail> {}
2063
2064impl<Head, Tail, P, Position> BirthProtocolAt<P, BirthProtocolTail<Position>>
2065 for BirthProtocol<Head, Tail>
2066where
2067 Head: Protocol,
2068 P: Protocol,
2069 Tail: BirthProtocolAt<P, Position>,
2070{
2071}
2072
2073#[doc(hidden)]
2075pub trait BirthProtocolProduct {
2076 type Append<Tail: BirthProtocolProduct>: BirthProtocolProduct;
2077}
2078
2079impl BirthProtocolProduct for NoBirthProtocols {
2080 type Append<Tail: BirthProtocolProduct> = Tail;
2081}
2082
2083impl<P, Rest> BirthProtocolProduct for BirthProtocol<P, Rest>
2084where
2085 P: Protocol,
2086 Rest: BirthProtocolProduct,
2087{
2088 type Append<Tail: BirthProtocolProduct> = BirthProtocol<P, Rest::Append<Tail>>;
2089}
2090
2091pub trait BirthProtocols: Behavior {
2097 type Protocols: BirthProtocolProduct;
2098}
2099
2100impl<B> BirthProtocols for B
2101where
2102 B: Behavior,
2103 B::Birth: BirthModeProtocols,
2104{
2105 type Protocols = BirthProtocol<B::Protocol, <B::Birth as BirthModeProtocols>::Protocols>;
2106}
2107
2108#[doc(hidden)]
2109pub trait BirthModeProtocols {
2110 type Protocols: BirthProtocolProduct;
2111}
2112
2113impl<M> BirthModeProtocols for M
2114where
2115 M: BirthMode,
2116 M::Child: BirthNodeProtocols,
2117{
2118 type Protocols = <M::Child as BirthNodeProtocols>::Protocols;
2119}
2120
2121#[doc(hidden)]
2122pub trait BirthNodeProtocols {
2123 type Protocols: BirthProtocolProduct;
2124}
2125
2126impl<B> BirthNodeProtocols for B
2127where
2128 B: BirthProtocols,
2129{
2130 type Protocols = B::Protocols;
2131}
2132
2133impl<Head, Tail> BirthNodeProtocols for ChildChoice<Head, Tail>
2134where
2135 Head: BirthNodeProtocols,
2136 Tail: BirthNodeProtocols,
2137{
2138 type Protocols = <Head::Protocols as BirthProtocolProduct>::Append<Tail::Protocols>;
2139}
2140
2141impl BirthNodeProtocols for Never {
2142 type Protocols = NoBirthProtocols;
2143}
2144
2145#[doc(hidden)]
2150pub trait BirthNodeLogicalHosts {
2151 type LogicalHosts: BirthProtocolProduct;
2152}
2153
2154impl<B> BirthNodeLogicalHosts for B
2155where
2156 B: crate::LogicalHostRequirements,
2157{
2158 type LogicalHosts = B::LogicalHosts;
2159}
2160
2161impl<Head, Tail> BirthNodeLogicalHosts for ChildChoice<Head, Tail>
2162where
2163 Head: BirthNodeLogicalHosts,
2164 Tail: BirthNodeLogicalHosts,
2165{
2166 type LogicalHosts = <Head::LogicalHosts as BirthProtocolProduct>::Append<Tail::LogicalHosts>;
2167}
2168
2169impl BirthNodeLogicalHosts for Never {
2170 type LogicalHosts = NoBirthProtocols;
2171}
2172
2173#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2175pub struct NoBirths;
2176
2177impl BirthMode for NoBirths {
2178 type Child = Never;
2179}
2180
2181#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2183pub struct Births<C>(PhantomData<fn() -> C>);
2184
2185impl<C> BirthMode for Births<C> {
2186 type Child = C;
2187}
2188
2189#[cfg(test)]
2190mod tests {
2191 use super::*;
2192 use crate::{Actions, BehaviorActed, NoBirths, User};
2193
2194 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
2195 struct TestAddr(u64);
2196
2197 impl Address for TestAddr {
2198 type Nonce = u64;
2199 }
2200
2201 struct TestEndpoint<P>(PhantomData<fn() -> P>);
2202
2203 impl<P> Clone for TestEndpoint<P> {
2204 fn clone(&self) -> Self {
2205 *self
2206 }
2207 }
2208
2209 impl<P> Copy for TestEndpoint<P> {}
2210
2211 impl EndpointAddress for TestAddr {
2212 type Established<P>
2213 = TestEndpoint<P>
2214 where
2215 P: Protocol<Addr = Self>;
2216 }
2217
2218 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2219 struct Child;
2220
2221 struct SharedProtocol;
2222
2223 impl behavior::Protocol for SharedProtocol {
2224 type Addr = TestAddr;
2225 type Msg = u8;
2226 }
2227
2228 struct Primary;
2229 struct Fallback;
2230
2231 macro_rules! shared_protocol_behavior {
2232 ($behavior:ty, $birth:ty) => {
2233 impl Behavior for $behavior {
2234 type Protocol = SharedProtocol;
2235 type Event = User<TestAddr, u8>;
2236 type Sends = Vec<Never>;
2237 type Ph = Never;
2238 type Error = Never;
2239 type Birth = $birth;
2240
2241 fn transition(
2242 &mut self,
2243 _: crate::ActiveTurn,
2244 _: Self::Event,
2245 ) -> BehaviorActed<Self> {
2246 Ok(Actions::cont())
2247 }
2248 }
2249 };
2250 }
2251
2252 shared_protocol_behavior!(Primary, Births<Child>);
2253 shared_protocol_behavior!(Fallback, NoBirths);
2254
2255 impl behavior::Protocol for Child {
2256 type Addr = TestAddr;
2257 type Msg = u8;
2258 }
2259
2260 impl Behavior for Child {
2261 type Protocol = Self;
2262 type Event = User<TestAddr, u8>;
2263 type Sends = Vec<Never>;
2264 type Ph = Never;
2265 type Error = Never;
2266 type Birth = NoBirths;
2267
2268 fn transition(&mut self, _: crate::ActiveTurn, _: Self::Event) -> BehaviorActed<Self> {
2269 Ok(Actions::cont())
2270 }
2271 }
2272
2273 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2274 enum ChildPlan {
2275 CreateChild,
2276 RejectBeforeTransfer,
2277 }
2278
2279 struct RecordingHost {
2280 calls: usize,
2281 observed: Vec<(CreationId, u64, CreationKind)>,
2282 plan: ChildPlan,
2283 }
2284
2285 #[derive(Debug, PartialEq, Eq)]
2286 enum SharedCreation {
2287 Primary(CreationId, u64),
2288 Fallback(CreationId, u64),
2289 }
2290
2291 #[derive(Default)]
2292 struct SharedProtocolHost(Vec<SharedCreation>);
2293
2294 impl EstablishChild<ChildHead, Primary> for SharedProtocolHost {
2295 async fn establish_child(
2296 &mut self,
2297 creation: RoutedCreation<TestAddr, Primary>,
2298 ) -> ItemSettlement<
2299 RoutedCreation<TestAddr, Primary>,
2300 ChildCreationOutcome<Primary, ChildHead>,
2301 CreationRejection,
2302 Never,
2303 > {
2304 let id = creation.id();
2305 let kind = creation.kind();
2306 let route = creation.route();
2307 let (creation, _) = creation.into_parts();
2308 let (_, _child, _) = creation.into_parts();
2309 self.0.push(SharedCreation::Primary(id, route));
2310 ItemSettlement::Accepted(ChildCreationOutcome::Established {
2311 established: EstablishedCreation::installed(
2312 id,
2313 kind,
2314 EstablishedRecipient::issued(TestEndpoint(PhantomData)),
2315 ),
2316 })
2317 }
2318 }
2319
2320 impl EstablishChild<ChildTail<ChildHead>, Fallback> for SharedProtocolHost {
2321 async fn establish_child(
2322 &mut self,
2323 creation: RoutedCreation<TestAddr, Fallback>,
2324 ) -> ItemSettlement<
2325 RoutedCreation<TestAddr, Fallback>,
2326 ChildCreationOutcome<Fallback, ChildTail<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::Fallback(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<ChildHead, Child> for RecordingHost {
2347 async fn establish_child(
2348 &mut self,
2349 creation: RoutedCreation<TestAddr, Child>,
2350 ) -> ItemSettlement<
2351 RoutedCreation<TestAddr, Child>,
2352 ChildCreationOutcome<Child, ChildHead>,
2353 CreationRejection,
2354 Never,
2355 > {
2356 self.calls += 1;
2357 self.observed
2358 .push((creation.id(), creation.route(), creation.kind()));
2359 match self.plan {
2360 ChildPlan::CreateChild => {
2361 let id = creation.id();
2362 let kind = creation.kind();
2363 let (creation, _) = creation.into_parts();
2364 let (_, _child, _) = creation.into_parts();
2365 ItemSettlement::Accepted(ChildCreationOutcome::Established {
2366 established: EstablishedCreation::installed(
2367 id,
2368 kind,
2369 EstablishedRecipient::issued(TestEndpoint(PhantomData)),
2370 ),
2371 })
2372 }
2373 ChildPlan::RejectBeforeTransfer => ItemSettlement::Rejected {
2374 item: creation,
2375 reason: CreationRejection::EnvironmentFailed,
2376 },
2377 }
2378 }
2379 }
2380
2381 fn host(plan: ChildPlan) -> RecordingHost {
2382 RecordingHost {
2383 calls: 0,
2384 observed: Vec::new(),
2385 plan,
2386 }
2387 }
2388
2389 fn assert_send<T: Send>(_: &T) {}
2390
2391 #[test]
2392 fn empty_child_product_stages_no_creations() {
2393 let creations = <NoChildren as ChildProduct<TestAddr>>::stage(NoChildren);
2394 assert!(creations.is_empty());
2395 }
2396
2397 #[test]
2398 fn creation_values_preserve_ids_order_and_debug_identity() {
2399 let mut sequence = CreationSequence::new();
2400 let first = sequence.issue().expect("the first creation ID exists");
2401 let second = sequence.issue().expect("the second creation ID exists");
2402 assert_eq!(first.get(), 1);
2403 assert_eq!(second.get(), 2);
2404
2405 let first_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2406 let same_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(first);
2407 let second_correlation = CreationCorrelation::<SharedProtocol, ChildHead>::new(second);
2408 assert_eq!(first_correlation, same_correlation);
2409 assert_ne!(first_correlation, second_correlation);
2410 assert_eq!(
2411 format!("{first_correlation:?}"),
2412 "CreationCorrelation(CreationId(1))"
2413 );
2414
2415 let mut creations = Creations::one(1_u8);
2416 creations.extend([2, 3]);
2417 assert_eq!(creations.len(), 3);
2418 assert!(!creations.is_empty());
2419 assert_eq!(creations.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
2420 assert_eq!(
2421 (&creations).into_iter().copied().collect::<Vec<_>>(),
2422 [1, 2, 3]
2423 );
2424
2425 let collected: Creations<_> = [4_u8, 5].into_iter().collect();
2426 assert_eq!(collected.len(), 2);
2427 assert_eq!(collected.into_iter().collect::<Vec<_>>(), [4, 5]);
2428
2429 let returned = ChildCreationSettled::<Child, ChildHead>::new(SettledItem::Unattempted(
2430 RoutedCreation::new(CreateChild::birth(first, Child), 17),
2431 ));
2432 assert_eq!(format!("{returned:?}"), "ChildCreationSettled { .. }");
2433 }
2434
2435 #[tokio::test]
2436 async fn concrete_child_dispatches_once_with_exact_creation_and_route() {
2437 let mut sequence = CreationSequence::new();
2438 let previous = sequence.issue().expect("the previous ID exists");
2439 let id = sequence.issue().expect("the replacement ID exists");
2440 let mut host = host(ChildPlan::CreateChild);
2441 let kind = CreationKind::replacement(previous);
2442 let future = Child.dispatch_birth(id, 17, kind, &mut host);
2443 assert_send(&future);
2444 let result = future.await;
2445
2446 let ItemSettlement::Accepted(ChildCreationOutcome::Established { established }) = result
2447 else {
2448 panic!("expected the child to be created");
2449 };
2450 assert_eq!(established.id(), id);
2451 assert_eq!(host.calls, 1);
2452 assert_eq!(host.observed, [(id, 17, kind)]);
2453 }
2454
2455 #[tokio::test]
2456 async fn concrete_child_returns_the_exact_rejected_creation_without_retry() {
2457 let mut sequence = CreationSequence::new();
2458 let previous = sequence.issue().expect("the previous ID exists");
2459 let id = sequence.issue().expect("the replacement ID exists");
2460 let mut host = host(ChildPlan::RejectBeforeTransfer);
2461 let kind = CreationKind::replacement(previous);
2462 let future = Child.dispatch_birth(id, 23, kind, &mut host);
2463 assert_send(&future);
2464 let result = future.await;
2465
2466 let ItemSettlement::Rejected { item, reason } = result else {
2467 panic!("expected refusal before child ownership transfer");
2468 };
2469 assert_eq!(
2470 item,
2471 RoutedCreation::new(CreateChild::replacement(id, previous, Child), 23)
2472 );
2473 assert_eq!(reason, CreationRejection::EnvironmentFailed);
2474 assert_eq!(host.calls, 1);
2475 assert_eq!(host.observed, [(id, 23, kind)]);
2476 }
2477
2478 #[tokio::test]
2479 async fn distinct_child_alternatives_preserve_one_canonical_protocol_identity() {
2480 type Alternatives = ChildChoice<Primary, ChildChoice<Fallback, Never>>;
2481
2482 fn requires_shared_protocol<C: Behavior<Protocol = SharedProtocol>>() {}
2483 requires_shared_protocol::<Primary>();
2484 requires_shared_protocol::<Fallback>();
2485
2486 let mut sequence = CreationSequence::new();
2487 let primary_id = sequence.issue().expect("the primary ID exists");
2488 let fallback_id = sequence.issue().expect("the fallback ID exists");
2489 let mut host = SharedProtocolHost::default();
2490 let primary = Alternatives::Head(Primary)
2491 .dispatch_birth(primary_id, 11, CreationKind::Birth, &mut host)
2492 .await;
2493 let fallback = Alternatives::Tail(ChildChoice::Head(Fallback))
2494 .dispatch_birth(fallback_id, 17, CreationKind::Birth, &mut host)
2495 .await;
2496
2497 let ItemSettlement::Accepted(ChildChoice::Head(ChildCreationOutcome::Established {
2498 established: primary,
2499 })) = primary
2500 else {
2501 panic!("expected the primary child result");
2502 };
2503 assert_eq!(primary.id(), primary_id);
2504 let ItemSettlement::Accepted(ChildChoice::Tail(ChildChoice::Head(
2505 ChildCreationOutcome::Established {
2506 established: fallback,
2507 },
2508 ))) = fallback
2509 else {
2510 panic!("expected the fallback child result");
2511 };
2512 assert_eq!(fallback.id(), fallback_id);
2513
2514 assert_eq!(
2515 host.0,
2516 [
2517 SharedCreation::Primary(primary_id, 11),
2518 SharedCreation::Fallback(fallback_id, 17),
2519 ]
2520 );
2521 }
2522
2523 #[test]
2524 fn birth_protocol_projection_recurses_without_inspecting_send_lanes() {
2525 type Protocols = <Primary as BirthProtocols>::Protocols;
2526 type Expected = BirthProtocol<SharedProtocol, BirthProtocol<Child, NoBirthProtocols>>;
2527
2528 trait Same<T> {}
2529 impl<T> Same<T> for T {}
2530 fn exact<T: Same<Expected>>() {}
2531 exact::<Protocols>();
2532 }
2533}