gosh_lan_transfer/events.rs
1// SPDX-License-Identifier: MIT
2//! Event handling infrastructure for gosh-lan-transfer
3//!
4//! This module provides the `EventHandler` trait and implementations
5//! for receiving engine events. The event types themselves are defined
6//! in the `protocol` module.
7
8use crate::protocol::EngineEvent;
9use std::sync::Arc;
10use tokio::sync::broadcast;
11
12/// Trait for receiving engine events
13///
14/// Implement this trait to handle events in your application.
15/// The engine will call `on_event` whenever an event occurs.
16///
17/// # Example
18///
19/// ```ignore
20/// use gosh_lan_transfer::{EventHandler, EngineEvent};
21///
22/// struct MyHandler;
23///
24/// impl EventHandler for MyHandler {
25/// fn on_event(&self, event: EngineEvent) {
26/// match event {
27/// EngineEvent::TransferProgress(p) => {
28/// println!("Progress: {}%", (p.bytes_transferred * 100) / p.total_bytes);
29/// }
30/// _ => {}
31/// }
32/// }
33/// }
34/// ```
35pub trait EventHandler: Send + Sync + 'static {
36 /// Called when an engine event occurs
37 fn on_event(&self, event: EngineEvent);
38}
39
40/// Channel-based event handler for async consumers
41///
42/// This handler uses a broadcast channel to distribute events,
43/// allowing multiple receivers to subscribe.
44pub struct ChannelEventHandler {
45 sender: broadcast::Sender<EngineEvent>,
46}
47
48impl ChannelEventHandler {
49 /// Create a new channel-based event handler
50 ///
51 /// # Arguments
52 /// * `capacity` - The capacity of the broadcast channel
53 ///
54 /// # Returns
55 /// A tuple of (handler, receiver) where receiver can be used to receive events
56 pub fn new(capacity: usize) -> (Self, broadcast::Receiver<EngineEvent>) {
57 let (sender, receiver) = broadcast::channel(capacity);
58 (Self { sender }, receiver)
59 }
60
61 /// Subscribe to receive events
62 ///
63 /// Multiple subscribers can receive the same events.
64 pub fn subscribe(&self) -> broadcast::Receiver<EngineEvent> {
65 self.sender.subscribe()
66 }
67}
68
69impl EventHandler for ChannelEventHandler {
70 fn on_event(&self, event: EngineEvent) {
71 // Ignore send errors (no receivers)
72 let _ = self.sender.send(event);
73 }
74}
75
76/// Callback-based event handler for simpler use cases
77///
78/// This handler invokes a callback function for each event.
79pub struct CallbackEventHandler<F>
80where
81 F: Fn(EngineEvent) + Send + Sync + 'static,
82{
83 callback: F,
84}
85
86impl<F> CallbackEventHandler<F>
87where
88 F: Fn(EngineEvent) + Send + Sync + 'static,
89{
90 /// Create a new callback-based event handler
91 ///
92 /// # Arguments
93 /// * `callback` - The function to call for each event
94 pub fn new(callback: F) -> Self {
95 Self { callback }
96 }
97}
98
99impl<F> EventHandler for CallbackEventHandler<F>
100where
101 F: Fn(EngineEvent) + Send + Sync + 'static,
102{
103 fn on_event(&self, event: EngineEvent) {
104 (self.callback)(event);
105 }
106}
107
108/// No-op event handler that discards all events
109///
110/// Useful for testing or when events are not needed.
111pub struct NoopEventHandler;
112
113impl EventHandler for NoopEventHandler {
114 fn on_event(&self, _event: EngineEvent) {
115 // Discard event
116 }
117}
118
119/// Helper function to create an Arc-wrapped channel event handler
120pub fn channel_handler(
121 capacity: usize,
122) -> (Arc<ChannelEventHandler>, broadcast::Receiver<EngineEvent>) {
123 let (handler, receiver) = ChannelEventHandler::new(capacity);
124 (Arc::new(handler), receiver)
125}
126
127/// Helper function to create an Arc-wrapped callback event handler
128pub fn callback_handler<F>(callback: F) -> Arc<CallbackEventHandler<F>>
129where
130 F: Fn(EngineEvent) + Send + Sync + 'static,
131{
132 Arc::new(CallbackEventHandler::new(callback))
133}
134
135/// Helper function to create an Arc-wrapped no-op event handler
136pub fn noop_handler() -> Arc<NoopEventHandler> {
137 Arc::new(NoopEventHandler)
138}