use crate::{ExitReason, Pid, Ref};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum SystemMessage {
Exit {
from: Pid,
reason: ExitReason,
},
Down {
monitor_ref: Ref,
pid: Pid,
reason: ExitReason,
},
Timeout,
}
impl SystemMessage {
pub fn exit(from: Pid, reason: ExitReason) -> Self {
SystemMessage::Exit { from, reason }
}
pub fn down(monitor_ref: Ref, pid: Pid, reason: ExitReason) -> Self {
SystemMessage::Down {
monitor_ref,
pid,
reason,
}
}
pub fn is_exit(&self) -> bool {
matches!(self, SystemMessage::Exit { .. })
}
pub fn is_down(&self) -> bool {
matches!(self, SystemMessage::Down { .. })
}
pub fn is_timeout(&self) -> bool {
matches!(self, SystemMessage::Timeout)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_exit_message() {
let pid = Pid::new();
let msg = SystemMessage::exit(pid, ExitReason::Normal);
assert!(msg.is_exit());
assert!(!msg.is_down());
assert!(!msg.is_timeout());
if let SystemMessage::Exit { from, reason } = msg {
assert_eq!(from, pid);
assert_eq!(reason, ExitReason::Normal);
} else {
panic!("expected Exit variant");
}
}
#[test]
fn test_down_message() {
let r = Ref::from_raw(100);
let pid = Pid::new();
let msg = SystemMessage::down(r, pid, ExitReason::Killed);
assert!(!msg.is_exit());
assert!(msg.is_down());
assert!(!msg.is_timeout());
if let SystemMessage::Down {
monitor_ref,
pid: p,
reason,
} = msg
{
assert_eq!(monitor_ref, r);
assert_eq!(p, pid);
assert_eq!(reason, ExitReason::Killed);
} else {
panic!("expected Down variant");
}
}
#[test]
fn test_timeout_message() {
let msg = SystemMessage::Timeout;
assert!(!msg.is_exit());
assert!(!msg.is_down());
assert!(msg.is_timeout());
}
#[test]
fn test_serialization() {
let pid1 = Pid::new();
let pid2 = Pid::new();
let messages = vec![
SystemMessage::exit(pid1, ExitReason::Normal),
SystemMessage::down(Ref::from_raw(42), pid2, ExitReason::Error("test".into())),
SystemMessage::Timeout,
];
for msg in messages {
let bytes = postcard::to_allocvec(&msg).unwrap();
let decoded: SystemMessage = postcard::from_bytes(&bytes).unwrap();
assert_eq!(msg, decoded);
}
}
}