hyperlane_plugin_websocket/websocket/
impl.rs

1use crate::*;
2
3/// Allows `String` to be used as a broadcast identifier.
4impl BroadcastTypeTrait for String {}
5/// Allows string slices to be used as broadcast identifiers.
6impl BroadcastTypeTrait for &str {}
7/// Allows `char` to be used as a broadcast identifier.
8impl BroadcastTypeTrait for char {}
9/// Allows `bool` to be used as a broadcast identifier.
10impl BroadcastTypeTrait for bool {}
11/// Allows `i8` to be used as a broadcast identifier.
12impl BroadcastTypeTrait for i8 {}
13/// Allows `i16` to be used as a broadcast identifier.
14impl BroadcastTypeTrait for i16 {}
15/// Allows `i32` to be used as a broadcast identifier.
16impl BroadcastTypeTrait for i32 {}
17/// Allows `i64` to be used as a broadcast identifier.
18impl BroadcastTypeTrait for i64 {}
19/// Allows `i128` to be used as a broadcast identifier.
20impl BroadcastTypeTrait for i128 {}
21/// Allows `isize` to be used as a broadcast identifier.
22impl BroadcastTypeTrait for isize {}
23/// Allows `u8` to be used as a broadcast identifier.
24impl BroadcastTypeTrait for u8 {}
25/// Allows `u16` to be used as a broadcast identifier.
26impl BroadcastTypeTrait for u16 {}
27/// Allows `u32` to be used as a broadcast identifier.
28impl BroadcastTypeTrait for u32 {}
29/// Allows `u64` to be used as a broadcast identifier.
30impl BroadcastTypeTrait for u64 {}
31/// Allows `u128` to be used as a broadcast identifier.
32impl BroadcastTypeTrait for u128 {}
33/// Allows `usize` to be used as a broadcast identifier.
34impl BroadcastTypeTrait for usize {}
35/// Allows `f32` to be used as a broadcast identifier.
36impl BroadcastTypeTrait for f32 {}
37/// Allows `f64` to be used as a broadcast identifier.
38impl BroadcastTypeTrait for f64 {}
39/// Allows `IpAddr` to be used as a broadcast identifier.
40impl BroadcastTypeTrait for IpAddr {}
41/// Allows `Ipv4Addr` to be used as a broadcast identifier.
42impl BroadcastTypeTrait for Ipv4Addr {}
43/// Allows `Ipv6Addr` to be used as a broadcast identifier.
44impl BroadcastTypeTrait for Ipv6Addr {}
45/// Allows `SocketAddr` to be used as a broadcast identifier.
46impl BroadcastTypeTrait for SocketAddr {}
47/// Allows `NonZeroU8` to be used as a broadcast identifier.
48impl BroadcastTypeTrait for NonZeroU8 {}
49/// Allows `NonZeroU16` to be used as a broadcast identifier.
50impl BroadcastTypeTrait for NonZeroU16 {}
51/// Allows `NonZeroU32` to be used as a broadcast identifier.
52impl BroadcastTypeTrait for NonZeroU32 {}
53/// Allows `NonZeroU64` to be used as a broadcast identifier.
54impl BroadcastTypeTrait for NonZeroU64 {}
55/// Allows `NonZeroU128` to be used as a broadcast identifier.
56impl BroadcastTypeTrait for NonZeroU128 {}
57/// Allows `NonZeroUsize` to be used as a broadcast identifier.
58impl BroadcastTypeTrait for NonZeroUsize {}
59/// Allows `NonZeroI8` to be used as a broadcast identifier.
60impl BroadcastTypeTrait for NonZeroI8 {}
61/// Allows `NonZeroI16` to be used as a broadcast identifier.
62impl BroadcastTypeTrait for NonZeroI16 {}
63/// Allows `NonZeroI32` to be used as a broadcast identifier.
64impl BroadcastTypeTrait for NonZeroI32 {}
65/// Allows `NonZeroI64` to be used as a broadcast identifier.
66impl BroadcastTypeTrait for NonZeroI64 {}
67/// Allows `NonZeroI128` to be used as a broadcast identifier.
68impl BroadcastTypeTrait for NonZeroI128 {}
69/// Allows `NonZeroIsize` to be used as a broadcast identifier.
70impl BroadcastTypeTrait for NonZeroIsize {}
71/// Allows `Infallible` to be used as a broadcast identifier.
72impl BroadcastTypeTrait for Infallible {}
73
74/// Allows references to `String` to be used as broadcast identifiers.
75impl BroadcastTypeTrait for &String {}
76/// Allows double references to string slices to be used as broadcast identifiers.
77impl BroadcastTypeTrait for &&str {}
78/// Allows references to `char` to be used as broadcast identifiers.
79impl BroadcastTypeTrait for &char {}
80/// Allows references to `bool` to be used as broadcast identifiers.
81impl BroadcastTypeTrait for &bool {}
82/// Allows references to `i8` to be used as broadcast identifiers.
83impl BroadcastTypeTrait for &i8 {}
84/// Allows references to `i16` to be used as broadcast identifiers.
85impl BroadcastTypeTrait for &i16 {}
86/// Allows references to `i32` to be used as broadcast identifiers.
87impl BroadcastTypeTrait for &i32 {}
88/// Allows references to `i64` to be used as broadcast identifiers.
89impl BroadcastTypeTrait for &i64 {}
90/// Allows references to `i128` to be used as broadcast identifiers.
91impl BroadcastTypeTrait for &i128 {}
92/// Allows references to `isize` to be used as broadcast identifiers.
93impl BroadcastTypeTrait for &isize {}
94/// Allows references to `u8` to be used as broadcast identifiers.
95impl BroadcastTypeTrait for &u8 {}
96/// Allows references to `u16` to be used as broadcast identifiers.
97impl BroadcastTypeTrait for &u16 {}
98/// Allows references to `u32` to be used as broadcast identifiers.
99impl BroadcastTypeTrait for &u32 {}
100/// Allows references to `u64` to be used as
101/// Implements `BroadcastTypeTrait` for `&u128`.
102///
103/// This allows references to `u128` to be used as a broadcast identifier.
104impl BroadcastTypeTrait for &u128 {}
105/// Implements `BroadcastTypeTrait` for `&usize`.
106///
107/// This allows references to `usize` to be used as a broadcast identifier.
108impl BroadcastTypeTrait for &usize {}
109/// Implements `BroadcastTypeTrait` for `&f32`.
110///
111/// This allows references to `f32` to be used as a broadcast identifier.
112impl BroadcastTypeTrait for &f32 {}
113/// Implements `BroadcastTypeTrait` for `&f64`.
114///
115/// This allows references to `f64` to be used as a broadcast identifier.
116impl BroadcastTypeTrait for &f64 {}
117/// Implements `BroadcastTypeTrait` for `&IpAddr`.
118///
119/// This allows references to `IpAddr` to be used as a broadcast identifier.
120impl BroadcastTypeTrait for &IpAddr {}
121/// Implements `BroadcastTypeTrait` for `&Ipv4Addr`.
122///
123/// This allows references to `Ipv4Addr` to be used as a broadcast identifier.
124impl BroadcastTypeTrait for &Ipv4Addr {}
125/// Implements `BroadcastTypeTrait` for `&Ipv6Addr`.
126///
127/// This allows references to `Ipv6Addr` to be used as a broadcast identifier.
128impl BroadcastTypeTrait for &Ipv6Addr {}
129/// Implements `BroadcastTypeTrait` for `&SocketAddr`.
130///
131/// This allows references to `SocketAddr` to be used as a broadcast identifier.
132impl BroadcastTypeTrait for &SocketAddr {}
133/// Implements `BroadcastTypeTrait` for `&NonZeroU8`.
134///
135/// This allows references to `NonZeroU8` to be used as a broadcast identifier.
136impl BroadcastTypeTrait for &NonZeroU8 {}
137/// Implements `BroadcastTypeTrait` for `&NonZeroU16`.
138///
139/// This allows references to `NonZeroU16` to be used as a broadcast identifier.
140impl BroadcastTypeTrait for &NonZeroU16 {}
141/// Implements `BroadcastTypeTrait` for `&NonZeroU32`.
142///
143/// This allows references to `NonZeroU32` to be used as a broadcast identifier.
144impl BroadcastTypeTrait for &NonZeroU32 {}
145/// Implements `BroadcastTypeTrait` for `&NonZeroU64`.
146///
147/// This allows references to `NonZeroU64` to be used as a broadcast identifier.
148impl BroadcastTypeTrait for &NonZeroU64 {}
149/// Implements `BroadcastTypeTrait` for `&NonZeroU128`.
150///
151/// This allows references to `NonZeroU128` to be used as a broadcast identifier.
152impl BroadcastTypeTrait for &NonZeroU128 {}
153/// Implements `BroadcastTypeTrait` for `&NonZeroUsize`.
154///
155/// This allows references to `NonZeroUsize` to be used as a broadcast identifier.
156impl BroadcastTypeTrait for &NonZeroUsize {}
157/// Implements `BroadcastTypeTrait` for `&NonZeroI8`.
158///
159/// This allows references to `NonZeroI8` to be used as a broadcast identifier.
160impl BroadcastTypeTrait for &NonZeroI8 {}
161/// Implements `BroadcastTypeTrait` for `&NonZeroI16`.
162///
163/// This allows references to `NonZeroI16` to be used as a broadcast identifier.
164impl BroadcastTypeTrait for &NonZeroI16 {}
165/// Implements `BroadcastTypeTrait` for `&NonZeroI32`.
166///
167/// This allows references to `NonZeroI32` to be used as a broadcast identifier.
168impl BroadcastTypeTrait for &NonZeroI32 {}
169/// Implements `BroadcastTypeTrait` for `&NonZeroI64`.
170///
171/// This allows references to `NonZeroI64` to be used as a broadcast identifier.
172impl BroadcastTypeTrait for &NonZeroI64 {}
173/// Implements `BroadcastTypeTrait` for `&NonZeroI128`.
174///
175/// This allows references to `NonZeroI128` to be used as a broadcast identifier.
176impl BroadcastTypeTrait for &NonZeroI128 {}
177/// Implements `BroadcastTypeTrait` for `&NonZeroIsize`.
178///
179/// This allows references to `NonZeroIsize` to be used as a broadcast identifier.
180impl BroadcastTypeTrait for &NonZeroIsize {}
181/// Implements `BroadcastTypeTrait` for `&Infallible`.
182///
183/// This allows references to `Infallible` to be used as a broadcast identifier.
184impl BroadcastTypeTrait for &Infallible {}
185
186/// Implements the `Default` trait for `BroadcastType`.
187///
188/// The default value is `BroadcastType::Unknown`.
189///
190/// # Type Parameters
191///
192/// - `B`: The type parameter for `BroadcastType`, which must implement `BroadcastTypeTrait`.
193impl<B: BroadcastTypeTrait> Default for BroadcastType<B> {
194    fn default() -> Self {
195        BroadcastType::Unknown
196    }
197}
198
199impl<B: BroadcastTypeTrait> BroadcastType<B> {
200    /// Generates a unique key string for a given broadcast type.
201    ///
202    /// For point-to-point types, the keys are sorted to ensure consistent key generation
203    /// regardless of the order of the input keys.
204    ///
205    /// # Arguments
206    ///
207    /// - `BroadcastType<B>` - The broadcast type for which to generate the key.
208    ///
209    /// # Returns
210    ///
211    /// - `String` - The unique key string for the broadcast type.
212    #[inline]
213    pub fn get_key(broadcast_type: BroadcastType<B>) -> String {
214        match broadcast_type {
215            BroadcastType::PointToPoint(key1, key2) => {
216                let (first_key, second_key) = if key1 <= key2 {
217                    (key1, key2)
218                } else {
219                    (key2, key1)
220                };
221                format!(
222                    "{}-{}-{}",
223                    POINT_TO_POINT_KEY,
224                    first_key.to_string(),
225                    second_key.to_string()
226                )
227            }
228            BroadcastType::PointToGroup(key) => {
229                format!("{}-{}", POINT_TO_GROUP_KEY, key.to_string())
230            }
231            BroadcastType::Unknown => String::new(),
232        }
233    }
234}
235
236/// Implements the `Default` trait for `WebSocketConfig`.
237///
238/// Provides a default configuration for WebSocket connections, including
239/// default hook types that do nothing.
240///
241/// # Type Parameters
242///
243/// - `B`: The type parameter for `WebSocketConfig`, which must implement `BroadcastTypeTrait`.
244impl<B: BroadcastTypeTrait> Default for WebSocketConfig<B> {
245    fn default() -> Self {
246        let default_hook: ServerHookHandler = Arc::new(|_ctx| Box::pin(async {}));
247        Self {
248            context: Context::default(),
249            buffer_size: DEFAULT_BUFFER_SIZE,
250            capacity: DEFAULT_BROADCAST_SENDER_CAPACITY,
251            broadcast_type: BroadcastType::default(),
252            connected_hook: default_hook.clone(),
253            request_hook: default_hook.clone(),
254            sended_hook: default_hook.clone(),
255            closed_hook: default_hook,
256        }
257    }
258}
259
260impl<B: BroadcastTypeTrait> WebSocketConfig<B> {
261    /// Creates a new WebSocket configuration with default values.
262    ///
263    /// # Returns
264    ///
265    /// - `WebSocketConfig<B>` - A new WebSocket configuration instance.
266    #[inline]
267    pub fn new() -> Self {
268        Self::default()
269    }
270}
271
272impl<B: BroadcastTypeTrait> WebSocketConfig<B> {
273    /// Sets the buffer size for the WebSocket connection.
274    ///
275    /// # Arguments
276    ///
277    /// - `usize` - The desired buffer size in bytes.
278    ///
279    /// # Returns
280    ///
281    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
282    #[inline]
283    pub fn set_buffer_size(mut self, buffer_size: usize) -> Self {
284        self.buffer_size = buffer_size;
285        self
286    }
287
288    /// Sets the capacity for the broadcast sender.
289    ///
290    /// # Arguments
291    ///
292    /// - `Capacity` - The desired capacity.
293    ///
294    /// # Returns
295    ///
296    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
297    #[inline]
298    pub fn set_capacity(mut self, capacity: Capacity) -> Self {
299        self.capacity = capacity;
300        self
301    }
302
303    /// Sets the context for the WebSocket connection.
304    ///
305    /// # Arguments
306    ///
307    /// - `Context` - The context object to associate with the WebSocket.
308    ///
309    /// # Returns
310    ///
311    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
312    #[inline]
313    pub fn set_context(mut self, context: Context) -> Self {
314        self.context = context;
315        self
316    }
317
318    /// Sets the broadcast type for the WebSocket connection.
319    ///
320    /// # Arguments
321    ///
322    /// - `BroadcastType<B>` - The broadcast type to use for this WebSocket.
323    ///
324    /// # Returns
325    ///
326    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
327    #[inline]
328    pub fn set_broadcast_type(mut self, broadcast_type: BroadcastType<B>) -> Self {
329        self.broadcast_type = broadcast_type;
330        self
331    }
332
333    /// Retrieves a reference to the context associated with this configuration.
334    ///
335    /// # Returns
336    ///
337    /// - `&Context` - A reference to the context object.
338    #[inline]
339    pub fn get_context(&self) -> &Context {
340        &self.context
341    }
342
343    /// Retrieves the buffer size configured for the WebSocket connection.
344    ///
345    /// # Returns
346    ///
347    /// - `usize` - The buffer size in bytes.
348    #[inline]
349    pub fn get_buffer_size(&self) -> usize {
350        self.buffer_size
351    }
352
353    /// Retrieves the capacity configured for the broadcast sender.
354    ///
355    /// # Returns
356    ///
357    /// - `Capacity` - The capacity.
358    #[inline]
359    pub fn get_capacity(&self) -> Capacity {
360        self.capacity
361    }
362
363    /// Retrieves a reference to the broadcast type configured for this WebSocket.
364    ///
365    /// # Returns
366    ///
367    /// - `&BroadcastType<B>` - A reference to the broadcast type object.
368    #[inline]
369    pub fn get_broadcast_type(&self) -> &BroadcastType<B> {
370        &self.broadcast_type
371    }
372
373    /// Sets the connected hook handler.
374    ///
375    /// This hook is executed when the WebSocket connection is established.
376    ///
377    /// # Type Parameters
378    ///
379    /// - `S`: The hook type, which must implement `ServerHook`.
380    ///
381    /// # Returns
382    ///
383    /// The modified `WebSocketConfig` instance.
384    ///
385    /// # Examples
386    ///
387    /// ```rust,ignore
388    /// struct MyConnectedHook;
389    /// impl ServerHook for MyConnectedHook {
390    ///     async fn new(_ctx: &Context) -> Self { Self }
391    ///     async fn handle(self, ctx: &Context) { /* ... */ }
392    /// }
393    ///
394    /// let config = WebSocketConfig::new()
395    ///     .set_connected_hook::<MyConnectedHook>();
396    /// ```
397    #[inline]
398    pub fn set_connected_hook<S>(mut self) -> Self
399    where
400        S: ServerHook,
401    {
402        self.connected_hook = server_hook_factory::<S>();
403        self
404    }
405
406    /// Sets the request hook handler.
407    ///
408    /// This hook is executed when a new request is received on the WebSocket.
409    ///
410    /// # Type Parameters
411    ///
412    /// - `S`: The hook type, which must implement `ServerHook`.
413    ///
414    /// # Returns
415    ///
416    /// The modified `WebSocketConfig` instance.
417    ///
418    /// # Examples
419    ///
420    /// ```rust,ignore
421    /// struct MyRequestHook;
422    /// impl ServerHook for MyRequestHook {
423    ///     async fn new(_ctx: &Context) -> Self { Self }
424    ///     async fn handle(self, ctx: &Context) { /* ... */ }
425    /// }
426    ///
427    /// let config = WebSocketConfig::new()
428    ///     .set_request_hook::<MyRequestHook>();
429    /// ```
430    #[inline]
431    pub fn set_request_hook<S>(mut self) -> Self
432    where
433        S: ServerHook,
434    {
435        self.request_hook = server_hook_factory::<S>();
436        self
437    }
438
439    /// Sets the sended hook handler.
440    ///
441    /// This hook is executed after a message has been successfully sent over the WebSocket.
442    ///
443    /// # Type Parameters
444    ///
445    /// - `S`: The hook type, which must implement `ServerHook`.
446    ///
447    /// # Returns
448    ///
449    /// The modified `WebSocketConfig` instance.
450    ///
451    /// # Examples
452    ///
453    /// ```rust,ignore
454    /// struct MySendedHook;
455    /// impl ServerHook for MySendedHook {
456    ///     async fn new(_ctx: &Context) -> Self { Self }
457    ///     async fn handle(self, ctx: &Context) { /* ... */ }
458    /// }
459    ///
460    /// let config = WebSocketConfig::new()
461    ///     .set_sended_hook::<MySendedHook>();
462    /// ```
463    #[inline]
464    pub fn set_sended_hook<S>(mut self) -> Self
465    where
466        S: ServerHook,
467    {
468        self.sended_hook = server_hook_factory::<S>();
469        self
470    }
471
472    /// Sets the closed hook handler.
473    ///
474    /// This hook is executed when the WebSocket connection is closed.
475    ///
476    /// # Type Parameters
477    ///
478    /// - `S`: The hook type, which must implement `ServerHook`.
479    ///
480    /// # Returns
481    ///
482    /// The modified `WebSocketConfig` instance.
483    ///
484    /// # Examples
485    ///
486    /// ```rust,ignore
487    /// struct MyClosedHook;
488    /// impl ServerHook for MyClosedHook {
489    ///     async fn new(_ctx: &Context) -> Self { Self }
490    ///     async fn handle(self, ctx: &Context) { /* ... */ }
491    /// }
492    ///
493    /// let config = WebSocketConfig::new()
494    ///     .set_closed_hook::<MyClosedHook>();
495    /// ```
496    #[inline]
497    pub fn set_closed_hook<S>(mut self) -> Self
498    where
499        S: ServerHook,
500    {
501        self.closed_hook = server_hook_factory::<S>();
502        self
503    }
504
505    /// Retrieves a reference to the connected hook handler.
506    ///
507    /// # Returns
508    ///
509    /// - `&ServerHookHandler` - A reference to the connected hook handler.
510    #[inline]
511    pub fn get_connected_hook(&self) -> &ServerHookHandler {
512        &self.connected_hook
513    }
514
515    /// Retrieves a reference to the request hook handler.
516    ///
517    /// # Returns
518    ///
519    /// - `&ServerHookHandler` - A reference to the request hook handler.
520    #[inline]
521    pub fn get_request_hook(&self) -> &ServerHookHandler {
522        &self.request_hook
523    }
524
525    /// Retrieves a reference to the sended hook handler.
526    ///
527    /// # Returns
528    ///
529    /// - `&ServerHookHandler` - A reference to the sended hook handler.
530    #[inline]
531    pub fn get_sended_hook(&self) -> &ServerHookHandler {
532        &self.sended_hook
533    }
534
535    /// Retrieves a reference to the closed hook handler.
536    ///
537    /// # Returns
538    ///
539    /// - `&ServerHookHandler` - A reference to the closed hook handler.
540    #[inline]
541    pub fn get_closed_hook(&self) -> &ServerHookHandler {
542        &self.closed_hook
543    }
544}
545
546impl WebSocket {
547    /// Creates a new WebSocket instance.
548    ///
549    /// Initializes with a default broadcast map.
550    ///
551    /// # Returns
552    ///
553    /// - `WebSocket` - A new WebSocket instance.
554    #[inline]
555    pub fn new() -> Self {
556        Self::default()
557    }
558
559    /// Subscribes to a broadcast type or inserts a new one if it doesn't exist.
560    ///
561    /// # Type Parameters
562    ///
563    /// - `B`: The type implementing `BroadcastTypeTrait`.
564    ///
565    /// # Arguments
566    ///
567    /// - `BroadcastType<B>` - The broadcast type to subscribe to.
568    /// - `Capacity` - The capacity for the broadcast sender if a new one is inserted.
569    ///
570    /// # Returns
571    ///
572    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the specified broadcast type.
573    #[inline]
574    fn subscribe_unwrap_or_insert<B: BroadcastTypeTrait>(
575        &self,
576        broadcast_type: BroadcastType<B>,
577        capacity: Capacity,
578    ) -> BroadcastMapReceiver<Vec<u8>> {
579        let key: String = BroadcastType::get_key(broadcast_type);
580        self.broadcast_map.subscribe_or_insert(&key, capacity)
581    }
582
583    /// Subscribes to a point-to-point broadcast.
584    ///
585    /// # Type Parameters
586    ///
587    /// - `B`: The type implementing `BroadcastTypeTrait`.
588    ///
589    /// # Arguments
590    ///
591    /// - `&B` - The first identifier for the point-to-point communication.
592    /// - `&B` - The second identifier for the point-to-point communication.
593    /// - `Capacity` - The capacity for the broadcast sender.
594    ///
595    /// # Returns
596    ///
597    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-point broadcast.
598    #[inline]
599    fn point_to_point<B: BroadcastTypeTrait>(
600        &self,
601        key1: &B,
602        key2: &B,
603        capacity: Capacity,
604    ) -> BroadcastMapReceiver<Vec<u8>> {
605        self.subscribe_unwrap_or_insert(
606            BroadcastType::PointToPoint(key1.clone(), key2.clone()),
607            capacity,
608        )
609    }
610
611    /// Subscribes to a point-to-group broadcast.
612    ///
613    /// # Type Parameters
614    ///
615    /// - `B`: The type implementing `BroadcastTypeTrait`.
616    ///
617    /// # Arguments
618    ///
619    /// - `&B` - The identifier for the group.
620    /// - `Capacity` - The capacity for the broadcast sender.
621    ///
622    /// # Returns
623    ///
624    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-group broadcast.
625    #[inline]
626    fn point_to_group<B: BroadcastTypeTrait>(
627        &self,
628        key: &B,
629        capacity: Capacity,
630    ) -> BroadcastMapReceiver<Vec<u8>> {
631        self.subscribe_unwrap_or_insert(BroadcastType::PointToGroup(key.clone()), capacity)
632    }
633
634    /// Retrieves the current receiver count for a given broadcast type.
635    ///
636    /// # Type Parameters
637    ///
638    /// - `B`: The type implementing `BroadcastTypeTrait`.
639    ///
640    /// # Arguments
641    ///
642    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
643    ///
644    /// # Returns
645    ///
646    /// - `ReceiverCount` - The number of active receivers for the broadcast type, or 0 if not found.
647    #[inline]
648    pub fn receiver_count<B: BroadcastTypeTrait>(
649        &self,
650        broadcast_type: BroadcastType<B>,
651    ) -> ReceiverCount {
652        let key: String = BroadcastType::get_key(broadcast_type);
653        self.broadcast_map.receiver_count(&key).unwrap_or(0)
654    }
655
656    /// Calculates the receiver count before a connection is established.
657    ///
658    /// Ensures the count does not exceed the maximum allowed value minus one.
659    ///
660    /// # Type Parameters
661    ///
662    /// - `B`: The type implementing `BroadcastTypeTrait`.
663    ///
664    /// # Arguments
665    ///
666    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
667    ///
668    /// # Returns
669    ///
670    /// - `ReceiverCount` - The receiver count after the connection is established.
671    #[inline]
672    pub fn receiver_count_before_connected<B: BroadcastTypeTrait>(
673        &self,
674        broadcast_type: BroadcastType<B>,
675    ) -> ReceiverCount {
676        let count: ReceiverCount = self.receiver_count(broadcast_type);
677        count.clamp(0, ReceiverCount::MAX - 1) + 1
678    }
679
680    /// Calculates the receiver count after a connection is closed.
681    ///
682    /// Ensures the count does not go below 0.
683    ///
684    /// # Type Parameters
685    ///
686    /// - `B`: The type implementing `BroadcastTypeTrait`.
687    ///
688    /// # Arguments
689    ///
690    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
691    ///
692    /// # Returns
693    ///
694    /// - `ReceiverCount` - The receiver count after the connection is closed.
695    #[inline]
696    pub fn receiver_count_after_closed<B: BroadcastTypeTrait>(
697        &self,
698        broadcast_type: BroadcastType<B>,
699    ) -> ReceiverCount {
700        let count: ReceiverCount = self.receiver_count(broadcast_type);
701        count.clamp(1, ReceiverCount::MAX) - 1
702    }
703
704    /// Sends data to all active receivers for a given broadcast type.
705    ///
706    /// # Type Parameters
707    ///
708    /// - `T`: The type of data to send, which must be convertible to `Vec<u8>`.
709    /// - `B`: The type implementing `BroadcastTypeTrait`.
710    ///
711    /// # Arguments
712    ///
713    /// - `BroadcastType<B>` - The broadcast type to which to send the data.
714    /// - `T` - The data to send.
715    ///
716    /// # Returns
717    ///
718    /// - `BroadcastMapSendResult<Vec<u8>>` - A result indicating the success or failure of the send operation.
719    #[inline]
720    pub fn send<T, B>(
721        &self,
722        broadcast_type: BroadcastType<B>,
723        data: T,
724    ) -> BroadcastMapSendResult<Vec<u8>>
725    where
726        T: Into<Vec<u8>>,
727        B: BroadcastTypeTrait,
728    {
729        let key: String = BroadcastType::get_key(broadcast_type);
730        self.broadcast_map.send(&key, data.into())
731    }
732
733    /// Runs the WebSocket connection, handling incoming requests and outgoing messages.
734    ///
735    /// This asynchronous function continuously monitors for new WebSocket requests
736    /// and incoming broadcast messages, processing them according to the configured hooks.
737    ///
738    /// # Type Parameters
739    ///
740    /// - `B`: The type implementing `BroadcastTypeTrait`.
741    ///
742    /// # Arguments
743    ///
744    /// - `WebSocketConfig<B>` - The WebSocket configuration containing the configuration for this WebSocket instance.
745    ///
746    /// # Panics
747    ///
748    /// Panics if the context in the WebSocket configuration is not set (i.e., it's the default context).
749    /// Panics if the broadcast type in the WebSocket configuration is `BroadcastType::Unknown`.
750    pub async fn run<B: BroadcastTypeTrait>(&self, config: WebSocketConfig<B>) {
751        let ctx: Context = config.get_context().clone();
752        if ctx.to_string() == Context::default().to_string() {
753            panic!("Context must be set");
754        }
755        let buffer_size: usize = config.get_buffer_size();
756        let capacity: Capacity = config.get_capacity();
757        let broadcast_type: BroadcastType<B> = config.get_broadcast_type().clone();
758        let mut receiver: Receiver<Vec<u8>> = match &broadcast_type {
759            BroadcastType::PointToPoint(key1, key2) => self.point_to_point(key1, key2, capacity),
760            BroadcastType::PointToGroup(key) => self.point_to_group(key, capacity),
761            BroadcastType::Unknown => panic!("BroadcastType must be PointToPoint or PointToGroup"),
762        };
763        let key: String = BroadcastType::get_key(broadcast_type);
764        config.get_connected_hook()(&ctx).await;
765        let result_handle = || async {
766            ctx.aborted().await;
767            ctx.closed().await;
768        };
769        loop {
770            tokio::select! {
771                request_res = ctx.ws_from_stream(buffer_size) => {
772                    let mut need_break = false;
773                    if request_res.is_ok() {
774                        config.get_request_hook()(&ctx).await;
775                    } else {
776                        need_break = true;
777                        config.get_closed_hook()(&ctx).await;
778                    }
779                    let body: ResponseBody = ctx.get_response_body().await;
780                    let is_err: bool = self.broadcast_map.send(&key, body).is_err();
781                    config.get_sended_hook()(&ctx).await;
782                    if need_break || is_err {
783                        break;
784                    }
785                },
786                msg_res = receiver.recv() => {
787                    if let Ok(msg) = &msg_res {
788                        let frame_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(msg);
789                        if ctx.send_body_list_with_data(&frame_list).await.is_ok() {
790                            continue;
791                        }
792                    }
793                    break;
794                }
795            }
796        }
797        result_handle().await;
798    }
799}