Skip to main content

monocoque_core/
monitor.rs

1//! Socket event monitoring.
2//!
3//! Provides event streams for tracking socket lifecycle events like
4//! connections, disconnections, and errors.
5
6use crate::endpoint::Endpoint;
7use std::fmt;
8
9/// Socket lifecycle events.
10#[derive(Debug, Clone)]
11pub enum SocketEvent {
12    /// Socket successfully connected to a peer.
13    Connected(Endpoint),
14
15    /// Socket disconnected from a peer.
16    Disconnected(Endpoint),
17
18    /// Socket successfully bound to an endpoint.
19    Bound(Endpoint),
20
21    /// Bind operation failed.
22    BindFailed { endpoint: Endpoint, reason: String },
23
24    /// Connection attempt failed.
25    ConnectFailed { endpoint: Endpoint, reason: String },
26
27    /// Socket is listening for incoming connections.
28    Listening(Endpoint),
29
30    /// Socket accepted a new incoming connection.
31    Accepted(Endpoint),
32}
33
34impl fmt::Display for SocketEvent {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match self {
37            Self::Connected(ep) => write!(f, "Connected to {ep}"),
38            Self::Disconnected(ep) => write!(f, "Disconnected from {ep}"),
39            Self::Bound(ep) => write!(f, "Bound to {ep}"),
40            Self::BindFailed { endpoint, reason } => {
41                write!(f, "Bind failed for {endpoint}: {reason}")
42            }
43            Self::ConnectFailed { endpoint, reason } => {
44                write!(f, "Connect failed for {endpoint}: {reason}")
45            }
46            Self::Listening(ep) => write!(f, "Listening on {ep}"),
47            Self::Accepted(ep) => write!(f, "Accepted connection from {ep}"),
48        }
49    }
50}
51
52/// Handle for receiving socket events.
53///
54/// This is a channel receiver that provides a stream of socket lifecycle events.
55pub type SocketMonitor = flume::Receiver<SocketEvent>;
56
57/// Internal sender for socket events.
58///
59/// This is exposed publicly to allow socket implementations to emit events.
60pub type SocketEventSender = flume::Sender<SocketEvent>;
61
62/// Creates a new monitoring channel pair.
63///
64/// This is exposed publicly to allow socket implementations to create monitors.
65#[must_use]
66pub fn create_monitor() -> (SocketEventSender, SocketMonitor) {
67    flume::unbounded()
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use std::net::SocketAddr;
74
75    #[test]
76    fn test_socket_event_display() {
77        let addr: SocketAddr = "127.0.0.1:5555".parse().unwrap();
78        let event = SocketEvent::Connected(Endpoint::Tcp(addr));
79        assert_eq!(event.to_string(), "Connected to tcp://127.0.0.1:5555");
80    }
81
82    #[test]
83    fn test_monitor_channel() {
84        let (sender, receiver) = create_monitor();
85        let addr: SocketAddr = "127.0.0.1:5555".parse().unwrap();
86        sender
87            .send(SocketEvent::Connected(Endpoint::Tcp(addr)))
88            .unwrap();
89
90        let event = receiver.recv().unwrap();
91        assert!(matches!(event, SocketEvent::Connected(_)));
92    }
93}