1mod established;
8
9pub use established::{
10 CancelObservation, EstablishedChild, EstablishedObservation, EstablishedShutdownResolved,
11 InterpretEstablishedObservation, InterpretEstablishedShutdown, ObservationAuthority,
12 ObservationId, ObservationOperation, ObservationRejection, ObservationRelationship,
13 ObserveEstablished, ObserveEstablishedCreation, ShutdownEstablished, ShutdownId,
14 ShutdownRejection, established_child,
15};
16
17use std::time::Duration;
18
19use std::time::Instant;
20
21use crate::{Crash, Exit};
22
23pub use behavior::CreationRejection;
24use behavior::{
25 ActionItem, Address, InterpretationProgress, ItemSettlement, Protocol, SourceAction,
26 finish_item, prepare_item,
27};
28use behavior::{CreationId, CreationKind};
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct TimerScheduled {
33 pub id: TimerId,
35 pub generation: TimerGeneration,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
41pub enum ScheduleAtRejection {
42 #[error("timer queue generation exhausted")]
44 QueueGenerationExhausted,
45 #[error("timer queue insertion sequence exhausted")]
47 QueueSequenceExhausted,
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
52pub enum ScheduleAfterRejection {
53 #[error("timer deadline overflowed")]
55 DeadlineOverflow,
56 #[error("timer queue generation exhausted")]
58 QueueGenerationExhausted,
59 #[error("timer queue insertion sequence exhausted")]
61 QueueSequenceExhausted,
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
65pub struct TimerId(pub u64);
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
68pub struct TimerGeneration(pub u64);
69
70impl From<u64> for TimerId {
71 fn from(value: u64) -> Self {
72 Self(value)
73 }
74}
75
76impl From<TimerId> for u64 {
77 fn from(value: TimerId) -> Self {
78 value.0
79 }
80}
81
82impl From<u64> for TimerGeneration {
83 fn from(value: u64) -> Self {
84 Self(value)
85 }
86}
87
88impl From<TimerGeneration> for u64 {
89 fn from(value: TimerGeneration) -> Self {
90 value.0
91 }
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
95pub struct ScheduleAt {
96 pub id: TimerId,
97 pub generation: TimerGeneration,
98 pub at: Instant,
99}
100
101impl ScheduleAt {
102 #[must_use]
103 pub const fn new(id: TimerId, generation: TimerGeneration, at: Instant) -> Self {
104 Self { id, generation, at }
105 }
106}
107
108impl From<(TimerId, TimerGeneration, Instant)> for ScheduleAt {
109 fn from((id, generation, at): (TimerId, TimerGeneration, Instant)) -> Self {
110 Self::new(id, generation, at)
111 }
112}
113
114impl behavior::InterpreterRequest for ScheduleAt {
115 type ReturnToEmitter = behavior::ReturnsToEmitter<TimerElapsed, behavior::Here>;
116 type LogicalProtocols = behavior::NoBirthProtocols;
117}
118
119impl ActionItem for ScheduleAt {
120 type Custody = (Option<Self>, Option<Self::Reply>);
121 type Input<'a>
122 = &'a mut Option<Self>
123 where
124 Self: 'a;
125 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
126
127 fn prepare_interpretation(
128 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
129 ) {
130 prepare_item::<Self>(progress);
131 }
132
133 fn interpretation_input<'a>(
134 custody: &'a mut Self::Custody,
135 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
136 where
137 Self: 'a,
138 {
139 match custody {
140 (input @ Some(_), received @ None) => Some((input, received)),
141 _ => None,
142 }
143 }
144
145 fn finish_interpretation(
146 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
147 ) {
148 finish_item::<Self>(progress);
149 }
150
151 type Accepted = TimerScheduled;
152 type Rejection = ScheduleAtRejection;
153 type Prerequisite = behavior::Never;
154}
155
156impl SourceAction for ScheduleAt {
157 type Source = Self;
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq)]
166pub struct ScheduleAfter {
167 pub id: TimerId,
168 pub generation: TimerGeneration,
169 pub after: Duration,
170}
171
172impl ScheduleAfter {
173 #[must_use]
174 pub const fn new(id: TimerId, generation: TimerGeneration, after: Duration) -> Self {
175 Self {
176 id,
177 generation,
178 after,
179 }
180 }
181}
182
183impl From<(TimerId, TimerGeneration, Duration)> for ScheduleAfter {
184 fn from((id, generation, after): (TimerId, TimerGeneration, Duration)) -> Self {
185 Self::new(id, generation, after)
186 }
187}
188
189impl behavior::InterpreterRequest for ScheduleAfter {
190 type ReturnToEmitter = behavior::ReturnsToEmitter<TimerElapsed, behavior::Here>;
191 type LogicalProtocols = behavior::NoBirthProtocols;
192}
193
194impl ActionItem for ScheduleAfter {
195 type Custody = (Option<Self>, Option<Self::Reply>);
196 type Input<'a>
197 = &'a mut Option<Self>
198 where
199 Self: 'a;
200 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
201
202 fn prepare_interpretation(
203 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
204 ) {
205 prepare_item::<Self>(progress);
206 }
207
208 fn interpretation_input<'a>(
209 custody: &'a mut Self::Custody,
210 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
211 where
212 Self: 'a,
213 {
214 match custody {
215 (input @ Some(_), received @ None) => Some((input, received)),
216 _ => None,
217 }
218 }
219
220 fn finish_interpretation(
221 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
222 ) {
223 finish_item::<Self>(progress);
224 }
225
226 type Accepted = TimerScheduled;
227 type Rejection = ScheduleAfterRejection;
228 type Prerequisite = behavior::Never;
229}
230
231impl SourceAction for ScheduleAfter {
232 type Source = Self;
233}
234
235#[derive(Debug, Clone, Copy, PartialEq, Eq)]
236pub struct TimerElapsed {
237 pub id: TimerId,
238 pub generation: TimerGeneration,
239}
240
241impl TimerElapsed {
242 #[must_use]
243 pub const fn new(id: TimerId, generation: TimerGeneration) -> Self {
244 Self { id, generation }
245 }
246}
247
248impl From<(TimerId, TimerGeneration)> for TimerElapsed {
249 fn from((id, generation): (TimerId, TimerGeneration)) -> Self {
250 Self::new(id, generation)
251 }
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq)]
266pub struct ObservePeer<A: Address> {
267 pub peer: A,
268}
269
270impl<A: Address> From<A> for ObservePeer<A> {
271 fn from(peer: A) -> Self {
272 Self::new(peer)
273 }
274}
275
276impl<A: Address> ObservePeer<A> {
277 #[must_use]
278 pub const fn new(peer: A) -> Self {
279 Self { peer }
280 }
281}
282
283#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
285pub enum PeerObservationRejection {
286 #[error("no actor incarnation exists at the requested logical address")]
289 UnknownAddress,
290}
291
292impl<A: Address> behavior::InterpreterRequest for ObservePeer<A> {
293 type ReturnToEmitter = behavior::ReturnsToEmitter<PeerStopped<A>, behavior::Here>;
294 type LogicalProtocols = behavior::NoBirthProtocols;
295}
296
297impl<A> ActionItem for ObservePeer<A>
301where
302 A: Address + Send,
303{
304 type Custody = (Option<Self>, Option<Self::Reply>);
305 type Input<'a>
306 = &'a mut Option<Self>
307 where
308 Self: 'a;
309 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
310
311 fn prepare_interpretation(
312 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
313 ) {
314 prepare_item::<Self>(progress);
315 }
316
317 fn interpretation_input<'a>(
318 custody: &'a mut Self::Custody,
319 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
320 where
321 Self: 'a,
322 {
323 match custody {
324 (input @ Some(_), received @ None) => Some((input, received)),
325 _ => None,
326 }
327 }
328
329 fn finish_interpretation(
330 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
331 ) {
332 finish_item::<Self>(progress);
333 }
334
335 type Accepted = ();
336 type Rejection = PeerObservationRejection;
337 type Prerequisite = behavior::Never;
338}
339
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
351pub struct UnwatchPeer<A> {
352 pub peer: A,
353}
354
355impl<A> UnwatchPeer<A> {
356 #[must_use]
357 pub const fn new(peer: A) -> Self {
358 Self { peer }
359 }
360}
361
362impl<A> From<A> for UnwatchPeer<A> {
363 fn from(peer: A) -> Self {
364 Self::new(peer)
365 }
366}
367
368#[derive(Debug, Clone, PartialEq, Eq)]
369pub struct PeerStopped<A: Address> {
370 pub peer: A,
371 pub outcome: Result<Exit<A>, Crash>,
372}
373
374impl<A: Address> PeerStopped<A> {
375 #[must_use]
376 pub fn new(peer: A, outcome: Result<Exit<A>, Crash>) -> Self {
377 Self { peer, outcome }
378 }
379}
380
381impl<A: Address> From<(A, Result<Exit<A>, Crash>)> for PeerStopped<A> {
382 fn from((peer, outcome): (A, Result<Exit<A>, Crash>)) -> Self {
383 Self { peer, outcome }
384 }
385}
386
387#[derive(Debug, Clone, Copy, PartialEq, Eq)]
388pub struct ChildStopped<A: Address> {
389 pub child: CreationId,
390 pub outcome: Result<Exit<A>, Crash>,
391 pub at: Instant,
392}
393
394impl<A: Address> ChildStopped<A> {
395 #[must_use]
396 pub fn new(child: CreationId, outcome: Result<Exit<A>, Crash>, at: Instant) -> Self {
397 Self { child, outcome, at }
398 }
399}
400
401impl<A: Address> From<(CreationId, Result<Exit<A>, Crash>, Instant)> for ChildStopped<A> {
402 fn from((child, outcome, at): (CreationId, Result<Exit<A>, Crash>, Instant)) -> Self {
403 Self { child, outcome, at }
404 }
405}
406
407pub struct ObserveChild<P: Protocol, Occurrence> {
434 pub child: CreationId,
435 protocol: core::marker::PhantomData<fn() -> P>,
436 occurrence: core::marker::PhantomData<fn() -> Occurrence>,
437}
438
439impl<P: Protocol, Occurrence> Copy for ObserveChild<P, Occurrence> {}
440
441impl<P: Protocol, Occurrence> Clone for ObserveChild<P, Occurrence> {
442 fn clone(&self) -> Self {
443 *self
444 }
445}
446
447impl<P: Protocol, Occurrence> PartialEq for ObserveChild<P, Occurrence> {
448 fn eq(&self, other: &Self) -> bool {
449 self.child == other.child
450 }
451}
452
453impl<P: Protocol, Occurrence> Eq for ObserveChild<P, Occurrence> {}
454
455impl<P: Protocol, Occurrence> core::fmt::Debug for ObserveChild<P, Occurrence> {
456 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
457 formatter
458 .debug_struct("ObserveChild")
459 .field("child", &self.child)
460 .finish()
461 }
462}
463
464impl<P: Protocol, Occurrence> ObserveChild<P, Occurrence> {
465 #[must_use]
466 pub const fn new(child: CreationId) -> Self {
467 Self {
468 child,
469 protocol: core::marker::PhantomData,
470 occurrence: core::marker::PhantomData,
471 }
472 }
473}
474
475impl<P: Protocol, Occurrence> behavior::InterpreterRequest for ObserveChild<P, Occurrence> {
476 type ReturnToEmitter = behavior::ReturnsToEmitter<ChildStopped<P::Addr>, behavior::Here>;
477 type LogicalProtocols = behavior::NoBirthProtocols;
478}
479
480impl<P, Occurrence> behavior::ActionItem for ObserveChild<P, Occurrence>
481where
482 P: Protocol,
483 <P::Addr as Address>::Nonce: Send,
484{
485 type Custody = (Option<Self>, Option<Self::Reply>);
486 type Input<'a>
487 = &'a mut Option<Self>
488 where
489 Self: 'a;
490 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
491
492 fn prepare_interpretation(
493 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
494 ) {
495 prepare_item::<Self>(progress);
496 }
497
498 fn interpretation_input<'a>(
499 custody: &'a mut Self::Custody,
500 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
501 where
502 Self: 'a,
503 {
504 match custody {
505 (input @ Some(_), received @ None) => Some((input, received)),
506 _ => None,
507 }
508 }
509
510 fn finish_interpretation(
511 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
512 ) {
513 finish_item::<Self>(progress);
514 }
515
516 type Accepted = ();
517 type Rejection = behavior::Never;
518 type Prerequisite = behavior::CreationCorrelation<P, Occurrence>;
519}
520
521#[derive(Debug, Clone, Copy, PartialEq, Eq)]
528pub struct CreationResolved<A: behavior::Address> {
529 pub creation: CreationId,
530 pub kind: CreationKind,
531 pub result: Result<A, CreationRejection>,
532}
533
534impl<A: behavior::Address> CreationResolved<A> {
535 #[must_use]
536 pub const fn new(
537 creation: CreationId,
538 kind: CreationKind,
539 result: Result<A, CreationRejection>,
540 ) -> Self {
541 Self {
542 creation,
543 kind,
544 result,
545 }
546 }
547
548 #[must_use]
549 pub const fn installed(creation: CreationId, kind: CreationKind, address: A) -> Self {
550 Self::new(creation, kind, Ok(address))
551 }
552
553 #[must_use]
555 pub const fn birth(creation: CreationId, address: A) -> Self {
556 Self::installed(creation, CreationKind::Birth, address)
557 }
558
559 #[must_use]
561 pub const fn replacement(creation: CreationId, previous: CreationId, address: A) -> Self {
562 Self::installed(creation, CreationKind::replacement(previous), address)
563 }
564
565 #[must_use]
566 pub const fn rejected(
567 creation: CreationId,
568 kind: CreationKind,
569 rejection: CreationRejection,
570 ) -> Self {
571 Self::new(creation, kind, Err(rejection))
572 }
573}
574
575impl<A: behavior::Address> From<(CreationId, CreationKind, Result<A, CreationRejection>)>
576 for CreationResolved<A>
577{
578 fn from(
579 (creation, kind, result): (CreationId, CreationKind, Result<A, CreationRejection>),
580 ) -> Self {
581 Self {
582 creation,
583 kind,
584 result,
585 }
586 }
587}
588
589pub struct ObserveCreation<P: Protocol, Occurrence> {
612 pub creation: CreationId,
613 occurrence: core::marker::PhantomData<fn() -> (P, Occurrence)>,
614}
615
616impl<P: Protocol, Occurrence> Copy for ObserveCreation<P, Occurrence> {}
617
618impl<P: Protocol, Occurrence> Clone for ObserveCreation<P, Occurrence> {
619 fn clone(&self) -> Self {
620 *self
621 }
622}
623
624impl<P: Protocol, Occurrence> PartialEq for ObserveCreation<P, Occurrence> {
625 fn eq(&self, other: &Self) -> bool {
626 self.creation == other.creation
627 }
628}
629
630impl<P: Protocol, Occurrence> Eq for ObserveCreation<P, Occurrence> {}
631
632impl<P: Protocol, Occurrence> core::fmt::Debug for ObserveCreation<P, Occurrence> {
633 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
634 formatter
635 .debug_struct("ObserveCreation")
636 .field("creation", &self.creation)
637 .finish()
638 }
639}
640
641impl<P: Protocol, Occurrence> ObserveCreation<P, Occurrence> {
642 #[must_use]
643 pub const fn new(creation: CreationId) -> Self {
644 Self {
645 creation,
646 occurrence: core::marker::PhantomData,
647 }
648 }
649}
650
651impl<P: Protocol, Occurrence> behavior::InterpreterRequest for ObserveCreation<P, Occurrence> {
652 type ReturnToEmitter = behavior::ReturnsToEmitter<CreationResolved<P::Addr>, behavior::Here>;
653 type LogicalProtocols = behavior::NoBirthProtocols;
654}
655
656impl<P, Occurrence> behavior::ActionItem for ObserveCreation<P, Occurrence>
657where
658 P: Protocol,
659 <P::Addr as Address>::Nonce: Send,
660{
661 type Custody = (Option<Self>, Option<Self::Reply>);
662 type Input<'a>
663 = &'a mut Option<Self>
664 where
665 Self: 'a;
666 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
667
668 fn prepare_interpretation(
669 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
670 ) {
671 prepare_item::<Self>(progress);
672 }
673
674 fn interpretation_input<'a>(
675 custody: &'a mut Self::Custody,
676 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
677 where
678 Self: 'a,
679 {
680 match custody {
681 (input @ Some(_), received @ None) => Some((input, received)),
682 _ => None,
683 }
684 }
685
686 fn finish_interpretation(
687 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
688 ) {
689 finish_item::<Self>(progress);
690 }
691
692 type Accepted = ();
693 type Rejection = behavior::Never;
694 type Prerequisite = behavior::CreationCorrelation<P, Occurrence>;
695}
696
697#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
699pub struct ShutdownRequested;
700
701pub struct ShutdownChild<C: behavior::Behavior, Occurrence> {
776 pub child: CreationId,
777 pub ingress: behavior::Ingress<ShutdownRequested, behavior::Here>,
779 protocol: core::marker::PhantomData<fn() -> (C, Occurrence)>,
780}
781
782impl<C: behavior::Behavior, Occurrence> ShutdownChild<C, Occurrence> {
783 #[must_use]
784 pub const fn new(child: CreationId) -> Self {
785 Self {
786 child,
787 ingress: behavior::Ingress::new(),
788 protocol: core::marker::PhantomData,
789 }
790 }
791}
792
793impl<C: behavior::Behavior, Occurrence> behavior::InterpreterRequest
794 for ShutdownChild<C, Occurrence>
795{
796 type ReturnToEmitter = behavior::ReturnsToEmitter<ChildShutdownRejected, behavior::Here>;
797 type LogicalProtocols = behavior::NoBirthProtocols;
798}
799
800impl<C, Occurrence> behavior::ActionItem for ShutdownChild<C, Occurrence>
801where
802 C: behavior::Behavior,
803 <behavior::BehaviorAddr<C> as behavior::Address>::Nonce: Send,
804{
805 type Custody = (Option<Self>, Option<Self::Reply>);
806 type Input<'a>
807 = &'a mut Option<Self>
808 where
809 Self: 'a;
810 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
811
812 fn prepare_interpretation(
813 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
814 ) {
815 prepare_item::<Self>(progress);
816 }
817
818 fn interpretation_input<'a>(
819 custody: &'a mut Self::Custody,
820 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
821 where
822 Self: 'a,
823 {
824 match custody {
825 (input @ Some(_), received @ None) => Some((input, received)),
826 _ => None,
827 }
828 }
829
830 fn finish_interpretation(
831 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
832 ) {
833 finish_item::<Self>(progress);
834 }
835
836 type Accepted = ();
837 type Rejection = ChildShutdownRejection;
838 type Prerequisite = behavior::CreationCorrelation<C::Protocol, Occurrence>;
839}
840
841impl<C: behavior::Behavior, Occurrence> Copy for ShutdownChild<C, Occurrence> {}
842
843impl<C: behavior::Behavior, Occurrence> Clone for ShutdownChild<C, Occurrence> {
844 fn clone(&self) -> Self {
845 *self
846 }
847}
848
849impl<C: behavior::Behavior, Occurrence> PartialEq for ShutdownChild<C, Occurrence> {
850 fn eq(&self, other: &Self) -> bool {
851 self.child == other.child
852 }
853}
854
855impl<C: behavior::Behavior, Occurrence> Eq for ShutdownChild<C, Occurrence> {}
856
857impl<C: behavior::Behavior, Occurrence> core::fmt::Debug for ShutdownChild<C, Occurrence> {
858 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
859 f.debug_struct("ShutdownChild")
860 .field("child", &self.child)
861 .finish()
862 }
863}
864
865#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
867pub enum ChildShutdownRejection {
868 #[error("no established child exists at the requested nonce")]
870 NotEstablished,
871 #[error("child shutdown is already in progress")]
873 AlreadyStopping,
874}
875
876#[derive(Debug, Clone, Copy, PartialEq, Eq)]
878pub struct ChildShutdownRejected {
879 pub child: CreationId,
880 pub reason: ChildShutdownRejection,
881}
882
883impl ChildShutdownRejected {
884 #[must_use]
885 pub const fn new(child: CreationId, reason: ChildShutdownRejection) -> Self {
886 Self { child, reason }
887 }
888}
889
890impl From<(CreationId, ChildShutdownRejection)> for ChildShutdownRejected {
891 fn from((child, reason): (CreationId, ChildShutdownRejection)) -> Self {
892 Self { child, reason }
893 }
894}
895
896#[cfg(test)]
897mod tests {
898 use super::*;
899 use behavior::MailAddr;
900
901 fn creation(number: u64) -> CreationId {
902 let mut sequence = behavior::CreationSequence::new();
903 (0..number)
904 .filter_map(|_| sequence.issue())
905 .last()
906 .unwrap_or_else(|| panic!("test creation ID is issued"))
907 }
908
909 #[test]
910 fn one_creation_correlates_observation_creation_and_shutdown() {
911 enum WorkerRole {}
912
913 struct Worker;
914
915 impl behavior::Protocol for Worker {
916 type Addr = MailAddr;
917 type Msg = behavior::Never;
918 }
919
920 impl behavior::Behavior for Worker {
921 type Protocol = Self;
922 type Event = behavior::User<MailAddr, behavior::Never>;
923 type Sends = Vec<behavior::Never>;
924 type Ph = behavior::Never;
925 type Error = behavior::Never;
926 type Birth = behavior::NoBirths;
927
928 fn transition(
929 &mut self,
930 _: behavior::ActiveTurn,
931 event: Self::Event,
932 ) -> behavior::BehaviorActed<Self> {
933 match event.message {}
934 }
935 }
936
937 let child = creation(13);
938
939 fn copy_without_occurrence_bounds<T: Copy>() {}
940 copy_without_occurrence_bounds::<ObserveChild<Worker, WorkerRole>>();
941 copy_without_occurrence_bounds::<ObserveCreation<Worker, WorkerRole>>();
942 copy_without_occurrence_bounds::<ShutdownChild<Worker, WorkerRole>>();
943
944 assert_eq!(ObserveChild::<Worker, WorkerRole>::new(child).child, child);
945 assert_eq!(
946 ObserveCreation::<Worker, WorkerRole>::new(child).creation,
947 child
948 );
949 assert_eq!(ShutdownChild::<Worker, WorkerRole>::new(child).child, child);
950 }
951
952 #[test]
953 fn expected_lane_types_infer_lossless_protocol_products() {
954 let peer: ObservePeer<MailAddr> = MailAddr(7).into();
955 let child: ObserveChild<
956 behavior::MessageProtocol<MailAddr, behavior::Never>,
957 behavior::ChildHead,
958 > = ObserveChild::new(creation(9));
959 let observed_creation: ObserveCreation<
960 behavior::MessageProtocol<MailAddr, behavior::Never>,
961 behavior::ChildHead,
962 > = ObserveCreation::new(creation(11));
963 let rejected: ChildShutdownRejected =
964 (creation(13), ChildShutdownRejection::NotEstablished).into();
965
966 assert_eq!(peer.peer, MailAddr(7));
967 assert_eq!(child.child.get(), 9);
968 assert_eq!(observed_creation.creation.get(), 11);
969 assert_eq!(rejected.child.get(), 13);
970 }
971
972 #[test]
973 fn timer_newtypes_and_requests_have_lossless_construction() {
974 let id = TimerId::from(2);
975 let generation = TimerGeneration::from(5);
976 assert_eq!(u64::from(id), 2);
977 assert_eq!(u64::from(generation), 5);
978 assert_eq!(
979 TimerElapsed::from((id, generation)),
980 TimerElapsed::new(id, generation)
981 );
982 }
983}