use behavior::{
Address, AtEvent, ChildEvent, ChildStopped, Exit, MailAddr, PeerEvent, PeerStopped,
ReceiveTimeoutEvent, Recipient, ServiceSends, ShutdownEvent, ShutdownProtocol,
ShutdownRequested, SupervisionEvent, TimeEvent, TimerElapsed, TimerGeneration, TimerId,
WatchEvent, WorkerEvent, WorkerStopped,
};
use tokio::time::Instant;
#[derive(Debug, Clone, PartialEq, Eq)]
enum Lane {
Time(TimerElapsed),
Peer(PeerStopped<MailAddr>),
Child(ChildStopped<MailAddr>),
Worker(WorkerStopped<MailAddr>),
Shutdown,
}
impl TimeEvent for Lane {
fn time_reached(event: TimerElapsed) -> Option<Self> {
Some(Self::Time(event))
}
}
impl PeerEvent<MailAddr> for Lane {
fn peer_stopped(event: PeerStopped<MailAddr>) -> Option<Self> {
Some(Self::Peer(event))
}
}
impl ChildEvent<MailAddr> for Lane {
fn child_stopped(event: ChildStopped<MailAddr>) -> Option<Self> {
Some(Self::Child(event))
}
}
impl WorkerEvent<MailAddr> for Lane {
fn worker_stopped(event: WorkerStopped<MailAddr>) -> Option<Self> {
Some(Self::Worker(event))
}
}
impl ShutdownEvent for Lane {
fn shutdown_requested(_: ShutdownRequested) -> Option<Self> {
Some(Self::Shutdown)
}
}
fn elapsed() -> TimerElapsed {
TimerElapsed {
id: TimerId(7),
generation: TimerGeneration(3),
}
}
fn peer() -> PeerStopped<MailAddr> {
PeerStopped {
peer: MailAddr(9),
outcome: Ok(Exit::Normal),
}
}
fn child() -> ChildStopped<MailAddr> {
ChildStopped {
nonce: 11,
outcome: Ok(Exit::Normal),
at: Instant::now(),
}
}
fn worker() -> WorkerStopped<MailAddr> {
WorkerStopped {
proxy: 13,
outcome: Ok(Exit::Normal),
at: Instant::now(),
}
}
#[test]
fn composed_protocols_forward_every_supported_environment_lane() {
assert!(matches!(
AtEvent::<Lane>::peer_stopped(peer()),
Some(AtEvent::Inner(Lane::Peer(_)))
));
assert!(matches!(
AtEvent::<Lane>::child_stopped(child()),
Some(AtEvent::Inner(Lane::Child(_)))
));
assert!(matches!(
AtEvent::<Lane>::worker_stopped(worker()),
Some(AtEvent::Inner(Lane::Worker(_)))
));
assert!(matches!(
WatchEvent::<Lane, MailAddr>::time_reached(elapsed()),
Some(WatchEvent::Inner(Lane::Time(_)))
));
assert!(matches!(
WatchEvent::<Lane, MailAddr>::child_stopped(child()),
Some(WatchEvent::Inner(Lane::Child(_)))
));
assert!(matches!(
WatchEvent::<Lane, MailAddr>::worker_stopped(worker()),
Some(WatchEvent::Inner(Lane::Worker(_)))
));
assert!(matches!(
ReceiveTimeoutEvent::<Lane>::time_reached(elapsed()),
Some(ReceiveTimeoutEvent::Elapsed(_))
));
assert!(matches!(
ReceiveTimeoutEvent::<Lane>::peer_stopped(peer()),
Some(ReceiveTimeoutEvent::Inner(Lane::Peer(_)))
));
assert!(matches!(
ReceiveTimeoutEvent::<Lane>::child_stopped(child()),
Some(ReceiveTimeoutEvent::Inner(Lane::Child(_)))
));
assert!(matches!(
ReceiveTimeoutEvent::<Lane>::worker_stopped(worker()),
Some(ReceiveTimeoutEvent::Inner(Lane::Worker(_)))
));
assert!(matches!(
ReceiveTimeoutEvent::<Lane>::shutdown_requested(ShutdownRequested),
Some(ReceiveTimeoutEvent::Inner(Lane::Shutdown))
));
assert!(matches!(
ShutdownProtocol::<Lane>::time_reached(elapsed()),
Some(ShutdownProtocol::Inner(Lane::Time(_)))
));
assert!(matches!(
ShutdownProtocol::<Lane>::peer_stopped(peer()),
Some(ShutdownProtocol::Inner(Lane::Peer(_)))
));
assert!(matches!(
ShutdownProtocol::<Lane>::child_stopped(child()),
Some(ShutdownProtocol::Inner(Lane::Child(_)))
));
assert!(matches!(
ShutdownProtocol::<Lane>::worker_stopped(worker()),
Some(ShutdownProtocol::Inner(Lane::Worker(_)))
));
assert!(matches!(
SupervisionEvent::<Lane, MailAddr>::child_stopped(child()),
Some(SupervisionEvent::ChildStopped(_))
));
assert!(matches!(
SupervisionEvent::<Lane, MailAddr>::worker_stopped(worker()),
Some(SupervisionEvent::WorkerStopped(_))
));
assert!(matches!(
SupervisionEvent::<Lane, MailAddr>::time_reached(elapsed()),
Some(SupervisionEvent::Inner(Lane::Time(_)))
));
assert!(matches!(
SupervisionEvent::<Lane, MailAddr>::peer_stopped(peer()),
Some(SupervisionEvent::Inner(Lane::Peer(_)))
));
assert!(matches!(
SupervisionEvent::<Lane, MailAddr>::shutdown_requested(ShutdownRequested),
Some(SupervisionEvent::Inner(Lane::Shutdown))
));
}
#[test]
fn addressing_operations_preserve_their_exact_routes() {
let parent = MailAddr(0xF0);
assert_eq!(
parent.birth(2),
MailAddr(0xF0 ^ 2_u64.wrapping_mul(0x9E37_79B9_7F4A_7C15))
);
let one = Recipient::<MailAddr, u8>::global(MailAddr(1));
let same = Recipient::<MailAddr, u8>::global(MailAddr(1));
let other = Recipient::<MailAddr, u8>::global(MailAddr(2));
let child = Recipient::<MailAddr, u8>::child(1);
assert_eq!(one, same);
assert_ne!(one, other);
assert_ne!(one, child);
assert_eq!(format!("{one:?}"), "Global(MailAddr(1))");
}
#[test]
fn service_send_views_and_iterators_preserve_every_request() {
let sends = ServiceSends::new(vec![3, 5, 8]);
assert_eq!(sends.as_slice(), &[3, 5, 8]);
assert!(!sends.is_empty());
assert_eq!(sends.clone().into_requests(), vec![3, 5, 8]);
assert_eq!(sends.clone().into_iter().collect::<Vec<_>>(), vec![3, 5, 8]);
assert_eq!(
(&sends).into_iter().copied().collect::<Vec<_>>(),
vec![3, 5, 8]
);
}