Skip to main content

hyperlane_plugin_websocket/
impl.rs

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