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}