From bb41e396aca01fee9f81785681fac0a79d0fd9d8 Mon Sep 17 00:00:00 2001 From: zirkonya Date: Thu, 27 Aug 2026 09:45:12 +0200 Subject: split event and enhance context --- src/event/connection.rs | 13 ++++++++++ src/event/disconnect.rs | 25 ++++++++++++++++++ src/event/handler.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ src/event/listener.rs | 47 ++++++++++++++++++++++++++++++++++ src/event/received.rs | 7 ++++++ src/event/sent.rs | 7 ++++++ 6 files changed, 166 insertions(+) create mode 100644 src/event/connection.rs create mode 100644 src/event/disconnect.rs create mode 100644 src/event/received.rs create mode 100644 src/event/sent.rs (limited to 'src/event') diff --git a/src/event/connection.rs b/src/event/connection.rs new file mode 100644 index 0000000..99813fd --- /dev/null +++ b/src/event/connection.rs @@ -0,0 +1,13 @@ +use std::net::SocketAddr; + +use getset::Getters; + +// TODO : identification +// TODO : reason type +#[derive(Getters)] +pub struct ConnectionEvent { + #[getset(get = "pub")] + peer_addr: SocketAddr, + #[getset(get = "pub")] + local_addr: SocketAddr, +} diff --git a/src/event/disconnect.rs b/src/event/disconnect.rs new file mode 100644 index 0000000..6511027 --- /dev/null +++ b/src/event/disconnect.rs @@ -0,0 +1,25 @@ +use std::io; + +use getset::Getters; + +// TODO : better error type for protocol violation +pub type ProtocolViolation = String; + +pub enum DisconnectReason { + Normal, + Error(io::Error), + ProtocolError(ProtocolViolation), + Timeout, + ServerShutdown, +} + +#[derive(Getters)] +pub struct DisconnectEvent +where + Uid: PartialEq, +{ + #[getset(get = "pub")] + connection_id: Uid, + #[getset(get = "pub")] + reason: DisconnectReason, +} diff --git a/src/event/handler.rs b/src/event/handler.rs index 7d8b5b5..3f9827e 100644 --- a/src/event/handler.rs +++ b/src/event/handler.rs @@ -1,2 +1,69 @@ // TODO : dispatch event through all listener // TODO : maybe compile listener into one ? + +use crate::{ + context::Context, + event::{ + Event, + listener::{Listener, ListenerResult}, + }, +}; + +pub struct EventHandler +where + Uid: PartialEq, +{ + listeners: Vec>>, +} + +impl EventHandler +where + Uid: PartialEq + Clone, +{ + pub fn register + 'static>(&mut self, listener: L) { + self.listeners.push(Box::new(listener)); + } + + pub fn dispatch(&self, event: &Event, ctx: &Context) { + match event.kind() { + super::EventKind::Connection(connection_event) => { + for listener in &self.listeners { + if matches!( + listener.on_connection(connection_event, ctx), + ListenerResult::Cancel | ListenerResult::Disconnect + ) { + event.cancel(); + break; + } + } + } + super::EventKind::PacketReceived(packet_received_event) => { + for listener in &self.listeners { + if matches!( + listener.on_packet_received(packet_received_event, ctx), + ListenerResult::Cancel | ListenerResult::Disconnect + ) { + event.cancel(); + break; + } + } + } + super::EventKind::PacketSent(packet_sent_event) => { + for listener in &self.listeners { + if matches!( + listener.on_packet_sent(packet_sent_event, ctx), + ListenerResult::Cancel | ListenerResult::Disconnect + ) { + event.cancel(); + break; + } + } + } + super::EventKind::Disconnect(disconnect_event) => { + for listener in &self.listeners { + listener.on_disconnect(disconnect_event, ctx); + } + } + } + } +} diff --git a/src/event/listener.rs b/src/event/listener.rs index 178dda8..81f4b57 100644 --- a/src/event/listener.rs +++ b/src/event/listener.rs @@ -1 +1,48 @@ +use crate::{ + context::Context, + event::{ConnectionEvent, DisconnectEvent, PacketReceivedEvent, PacketSentEvent}, +}; + // TODO : Listener ; interface to perform action when event occured +// TODO async trait for async runtime + +pub enum ListenerResult { + Continue, + /// Cancel the event + /// `ConectionEvent` => same as `ListenerResult::Disconnect` + /// `PacketReceived` => the received packet is drop + /// `PacketSent` => the packet isn't send + /// `Disconnect` => non sense + Cancel, + /// Force disconnect the connection + Disconnect, +} + +pub trait Listener +where + Uid: PartialEq, +{ + fn on_connection(&self, event: &ConnectionEvent, ctx: &Context) -> ListenerResult { + let _ = (event, ctx); + ListenerResult::Continue + } + fn on_packet_received( + &self, + event: &PacketReceivedEvent, + ctx: &Context, + ) -> ListenerResult { + let _ = (event, ctx); + ListenerResult::Continue + } + fn on_packet_sent( + &self, + event: &PacketSentEvent, + ctx: &Context, + ) -> ListenerResult { + let _ = (event, ctx); + ListenerResult::Continue + } + fn on_disconnect(&self, event: &DisconnectEvent, ctx: &Context) { + let _ = (event, ctx); + } +} diff --git a/src/event/received.rs b/src/event/received.rs new file mode 100644 index 0000000..0ef6d0e --- /dev/null +++ b/src/event/received.rs @@ -0,0 +1,7 @@ +use getset::Getters; + +#[derive(Getters)] +pub struct PacketReceivedEvent { + #[getset(get = "pub")] + packet: Packet, +} diff --git a/src/event/sent.rs b/src/event/sent.rs new file mode 100644 index 0000000..5278842 --- /dev/null +++ b/src/event/sent.rs @@ -0,0 +1,7 @@ +use getset::Getters; + +#[derive(Getters)] +pub struct PacketSentEvent { + #[getset(get = "pub")] + packet: Packet, +} -- cgit v1.2.3