deribit_websocket/
callback.rs

1//! Callback system for message handling
2
3use crate::error::WebSocketError;
4use std::sync::Arc;
5
6/// Primary message processing callback
7/// Takes a message and returns Result<(), Error> for processing
8pub type MessageCallback = Arc<dyn Fn(&str) -> Result<(), WebSocketError> + Send + Sync>;
9
10/// Error handling callback
11/// Takes the original message and the error from the primary callback
12/// Called only when the primary callback returns an error
13pub type ErrorCallback = Arc<dyn Fn(&str, &WebSocketError) + Send + Sync>;
14
15/// Message handler that combines both callbacks
16#[derive(Clone)]
17pub struct MessageHandler {
18    /// Primary callback for processing messages
19    pub message_callback: MessageCallback,
20    /// Error callback for handling processing failures
21    pub error_callback: ErrorCallback,
22}
23
24impl MessageHandler {
25    /// Create a new message handler with both callbacks
26    pub fn new<F, E>(message_callback: F, error_callback: E) -> Self
27    where
28        F: Fn(&str) -> Result<(), WebSocketError> + Send + Sync + 'static,
29        E: Fn(&str, &WebSocketError) + Send + Sync + 'static,
30    {
31        Self {
32            message_callback: Arc::new(message_callback),
33            error_callback: Arc::new(error_callback),
34        }
35    }
36
37    /// Process a message using the callback system
38    /// 1. Calls the primary callback with the message
39    /// 2. If primary callback returns error, calls error callback with message and error
40    pub fn handle_message(&self, message: &str) {
41        match (self.message_callback)(message) {
42            Ok(()) => {
43                // Message processed successfully, no further action needed
44            }
45            Err(error) => {
46                // Primary callback failed, call error callback
47                (self.error_callback)(message, &error);
48            }
49        }
50    }
51}
52
53impl std::fmt::Debug for MessageHandler {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        f.debug_struct("MessageHandler")
56            .field("message_callback", &"<callback function>")
57            .field("error_callback", &"<error callback function>")
58            .finish()
59    }
60}
61
62/// Builder for creating message handlers with fluent API
63pub struct MessageHandlerBuilder {
64    message_callback: Option<MessageCallback>,
65    error_callback: Option<ErrorCallback>,
66}
67
68impl Default for MessageHandlerBuilder {
69    fn default() -> Self {
70        Self::new()
71    }
72}
73
74impl MessageHandlerBuilder {
75    /// Create a new message handler builder
76    pub fn new() -> Self {
77        Self {
78            message_callback: None,
79            error_callback: None,
80        }
81    }
82
83    /// Set the primary message processing callback
84    pub fn with_message_callback<F>(mut self, callback: F) -> Self
85    where
86        F: Fn(&str) -> Result<(), WebSocketError> + Send + Sync + 'static,
87    {
88        self.message_callback = Some(Arc::new(callback));
89        self
90    }
91
92    /// Set the error handling callback
93    pub fn with_error_callback<E>(mut self, callback: E) -> Self
94    where
95        E: Fn(&str, &WebSocketError) + Send + Sync + 'static,
96    {
97        self.error_callback = Some(Arc::new(callback));
98        self
99    }
100
101    /// Build the message handler
102    /// Returns an error if either callback is missing
103    pub fn build(self) -> Result<MessageHandler, WebSocketError> {
104        let message_callback = self.message_callback.ok_or_else(|| {
105            WebSocketError::InvalidMessage("Message callback is required".to_string())
106        })?;
107
108        let error_callback = self.error_callback.ok_or_else(|| {
109            WebSocketError::InvalidMessage("Error callback is required".to_string())
110        })?;
111
112        Ok(MessageHandler {
113            message_callback,
114            error_callback,
115        })
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn test_message_handler_success() {
125        let handler = MessageHandler::new(
126            |_message| Ok(()),
127            |_message, _error| {
128                panic!("Error callback should not be called on success");
129            },
130        );
131
132        // This should not panic
133        handler.handle_message("test message");
134    }
135
136    #[test]
137    fn test_message_handler_error() {
138        use std::sync::{Arc, Mutex};
139
140        let error_called = Arc::new(Mutex::new(false));
141        let error_called_clone = error_called.clone();
142
143        let handler = MessageHandler::new(
144            |_message| Err(WebSocketError::InvalidMessage("Test error".to_string())),
145            move |_message, _error| {
146                *error_called_clone.lock().unwrap() = true;
147            },
148        );
149
150        handler.handle_message("test message");
151        assert!(*error_called.lock().unwrap());
152    }
153
154    #[test]
155    fn test_message_handler_builder() {
156        let handler = MessageHandlerBuilder::new()
157            .with_message_callback(|_| Ok(()))
158            .with_error_callback(|_, _| {})
159            .build()
160            .unwrap();
161
162        handler.handle_message("test");
163    }
164}