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
310impl<'a, B> WebSocketConfig<'a, B>
311where
312    B: BroadcastTypeTrait,
313{
314    /// Creates a new WebSocket configuration with the given context.
315    ///
316    /// # Arguments
317    ///
318    /// - `&mut Context` - The context object to associate with the WebSocket.
319    ///
320    /// # Returns
321    ///
322    /// - `WebSocketConfig<B>` - A new WebSocket configuration instance.
323    #[inline(always)]
324    pub fn new(stream: &'a mut Stream, context: &'a mut Context) -> Self {
325        Self {
326            stream,
327            context,
328            capacity: DEFAULT_BROADCAST_SENDER_CAPACITY,
329            broadcast_type: BroadcastType::default(),
330            connected_hook: default_server_hook_handler(),
331            request_hook: default_server_hook_handler(),
332            sended_hook: default_server_hook_handler(),
333            closed_hook: default_server_hook_handler(),
334        }
335    }
336}
337
338impl<'a, B> WebSocketConfig<'a, B>
339where
340    B: BroadcastTypeTrait,
341{
342    /// Sets the capacity for the broadcast sender.
343    ///
344    /// # Arguments
345    ///
346    /// - `Capacity` - The desired capacity.
347    ///
348    /// # Returns
349    ///
350    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
351    #[inline(always)]
352    pub fn set_capacity(mut self, capacity: Capacity) -> Self {
353        self.capacity = capacity;
354        self
355    }
356
357    /// Sets the context for the WebSocket connection.
358    ///
359    /// # Arguments
360    ///
361    /// - `&mut Context` - The context object to associate with the WebSocket.
362    ///
363    /// # Returns
364    ///
365    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
366    #[inline(always)]
367    pub fn set_context(mut self, context: &'a mut Context) -> Self {
368        self.context = context;
369        self
370    }
371
372    /// Sets the broadcast type for the WebSocket connection.
373    ///
374    /// # Arguments
375    ///
376    /// - `BroadcastType<B>` - The broadcast type to use for this WebSocket.
377    ///
378    /// # Returns
379    ///
380    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
381    #[inline(always)]
382    pub fn set_broadcast_type(mut self, broadcast_type: BroadcastType<B>) -> Self {
383        self.broadcast_type = broadcast_type;
384        self
385    }
386
387    #[inline(always)]
388    pub fn get_stream(&mut self) -> &mut Stream {
389        self.stream
390    }
391
392    /// Retrieves a reference to the context associated with this configuration.
393    ///
394    /// # Returns
395    ///
396    /// - `&mut Context` - A reference to the context object.
397    #[inline(always)]
398    pub fn get_context(&mut self) -> &mut Context {
399        self.context
400    }
401
402    /// Retrieves the capacity configured for the broadcast sender.
403    ///
404    /// # Returns
405    ///
406    /// - `Capacity` - The capacity.
407    #[inline(always)]
408    pub fn get_capacity(&self) -> Capacity {
409        self.capacity
410    }
411
412    /// Retrieves a reference to the broadcast type configured for this WebSocket.
413    ///
414    /// # Returns
415    ///
416    /// - `&BroadcastType<B>` - A reference to the broadcast type object.
417    #[inline(always)]
418    pub fn get_broadcast_type(&self) -> &BroadcastType<B> {
419        &self.broadcast_type
420    }
421
422    /// Sets the connected hook handler.
423    ///
424    /// This hook is executed when the WebSocket connection is established.
425    ///
426    /// # Type Parameters
427    ///
428    /// - `S`: The hook type, which must implement `ServerHook`.
429    ///
430    /// # Returns
431    ///
432    /// The modified `WebSocketConfig` instance.
433    ///
434    /// # Examples
435    ///
436    /// ```rust,ignore
437    /// struct MyConnectedHook;
438    /// impl ServerHook for MyConnectedHook {
439    ///     async fn new(_ctx: &Context) -> Self { Self }
440    ///     async fn handle(self, ctx: &Context) { /* ... */ }
441    /// }
442    ///
443    /// let config = WebSocketConfig::new()
444    ///     .set_connected_hook::<MyConnectedHook>();
445    /// ```
446    #[inline(always)]
447    pub fn set_connected_hook<S>(mut self) -> Self
448    where
449        S: ServerHook,
450    {
451        self.connected_hook = server_hook_factory::<S>();
452        self
453    }
454
455    /// Sets the request hook handler.
456    ///
457    /// This hook is executed when a new request is received on the WebSocket.
458    ///
459    /// # Type Parameters
460    ///
461    /// - `S`: The hook type, which must implement `ServerHook`.
462    ///
463    /// # Returns
464    ///
465    /// The modified `WebSocketConfig` instance.
466    ///
467    /// # Examples
468    ///
469    /// ```rust,ignore
470    /// struct MyRequestHook;
471    /// impl ServerHook for MyRequestHook {
472    ///     async fn new(_ctx: &Context) -> Self { Self }
473    ///     async fn handle(self, ctx: &Context) { /* ... */ }
474    /// }
475    ///
476    /// let config = WebSocketConfig::new()
477    ///     .set_request_hook::<MyRequestHook>();
478    /// ```
479    #[inline(always)]
480    pub fn set_request_hook<S>(mut self) -> Self
481    where
482        S: ServerHook,
483    {
484        self.request_hook = server_hook_factory::<S>();
485        self
486    }
487
488    /// Sets the sended hook handler.
489    ///
490    /// This hook is executed after a message has been successfully sent over the WebSocket.
491    ///
492    /// # Type Parameters
493    ///
494    /// - `S`: The hook type, which must implement `ServerHook`.
495    ///
496    /// # Returns
497    ///
498    /// The modified `WebSocketConfig` instance.
499    ///
500    /// # Examples
501    ///
502    /// ```rust,ignore
503    /// struct MySendedHook;
504    /// impl ServerHook for MySendedHook {
505    ///     async fn new(_ctx: &Context) -> Self { Self }
506    ///     async fn handle(self, ctx: &Context) { /* ... */ }
507    /// }
508    ///
509    /// let config = WebSocketConfig::new()
510    ///     .set_sended_hook::<MySendedHook>();
511    /// ```
512    #[inline(always)]
513    pub fn set_sended_hook<S>(mut self) -> Self
514    where
515        S: ServerHook,
516    {
517        self.sended_hook = server_hook_factory::<S>();
518        self
519    }
520
521    /// Sets the closed hook handler.
522    ///
523    /// This hook is executed when the WebSocket connection is closed.
524    ///
525    /// # Type Parameters
526    ///
527    /// - `S`: The hook type, which must implement `ServerHook`.
528    ///
529    /// # Returns
530    ///
531    /// The modified `WebSocketConfig` instance.
532    ///
533    /// # Examples
534    ///
535    /// ```rust,ignore
536    /// struct MyClosedHook;
537    /// impl ServerHook for MyClosedHook {
538    ///     async fn new(_ctx: &Context) -> Self { Self }
539    ///     async fn handle(self, ctx: &Context) { /* ... */ }
540    /// }
541    ///
542    /// let config = WebSocketConfig::new()
543    ///     .set_closed_hook::<MyClosedHook>();
544    /// ```
545    #[inline(always)]
546    pub fn set_closed_hook<S>(mut self) -> Self
547    where
548        S: ServerHook,
549    {
550        self.closed_hook = server_hook_factory::<S>();
551        self
552    }
553
554    /// Retrieves a reference to the connected hook handler.
555    ///
556    /// # Returns
557    ///
558    /// - `&ServerHookHandler` - A reference to the connected hook handler.
559    #[inline(always)]
560    pub fn get_connected_hook(&self) -> &ServerHookHandler {
561        &self.connected_hook
562    }
563
564    /// Retrieves a reference to the request hook handler.
565    ///
566    /// # Returns
567    ///
568    /// - `&ServerHookHandler` - A reference to the request hook handler.
569    #[inline(always)]
570    pub fn get_request_hook(&self) -> &ServerHookHandler {
571        &self.request_hook
572    }
573
574    /// Retrieves a reference to the sended hook handler.
575    ///
576    /// # Returns
577    ///
578    /// - `&ServerHookHandler` - A reference to the sended hook handler.
579    #[inline(always)]
580    pub fn get_sended_hook(&self) -> &ServerHookHandler {
581        &self.sended_hook
582    }
583
584    /// Retrieves a reference to the closed hook handler.
585    ///
586    /// # Returns
587    ///
588    /// - `&ServerHookHandler` - A reference to the closed hook handler.
589    #[inline(always)]
590    pub fn get_closed_hook(&self) -> &ServerHookHandler {
591        &self.closed_hook
592    }
593}
594
595impl WebSocket {
596    /// Creates a new WebSocket instance.
597    ///
598    /// Initializes with a default broadcast map.
599    ///
600    /// # Returns
601    ///
602    /// - `WebSocket` - A new WebSocket instance.
603    #[inline(always)]
604    pub fn new() -> Self {
605        Self::default()
606    }
607
608    /// Subscribes to a broadcast type or inserts a new one if it doesn't exist.
609    ///
610    /// # Type Parameters
611    ///
612    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
613    ///
614    /// # Arguments
615    ///
616    /// - `BroadcastType<B>` - The broadcast type to subscribe to.
617    /// - `Capacity` - The capacity for the broadcast sender if a new one is inserted.
618    ///
619    /// # Returns
620    ///
621    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the specified broadcast type.
622    #[inline(always)]
623    fn subscribe_unwrap_or_insert<B>(
624        &self,
625        broadcast_type: BroadcastType<B>,
626        capacity: Capacity,
627    ) -> BroadcastMapReceiver<Vec<u8>>
628    where
629        B: BroadcastTypeTrait,
630    {
631        let key: String = BroadcastType::get_key(broadcast_type);
632        self.broadcast_map.subscribe_or_insert(&key, capacity)
633    }
634
635    /// Subscribes to a point-to-point broadcast.
636    ///
637    /// # Type Parameters
638    ///
639    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
640    ///
641    /// # Arguments
642    ///
643    /// - `&BroadcastTypeTrait` - The first identifier for the point-to-point communication.
644    /// - `&BroadcastTypeTrait` - The second identifier for the point-to-point communication.
645    /// - `Capacity` - The capacity for the broadcast sender.
646    ///
647    /// # Returns
648    ///
649    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-point broadcast.
650    #[inline(always)]
651    fn point_to_point<B>(
652        &self,
653        key1: &B,
654        key2: &B,
655        capacity: Capacity,
656    ) -> BroadcastMapReceiver<Vec<u8>>
657    where
658        B: BroadcastTypeTrait,
659    {
660        self.subscribe_unwrap_or_insert(
661            BroadcastType::PointToPoint(key1.clone(), key2.clone()),
662            capacity,
663        )
664    }
665
666    /// Subscribes to a point-to-group broadcast.
667    ///
668    /// # Type Parameters
669    ///
670    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
671    ///
672    /// # Arguments
673    ///
674    /// - `&BroadcastTypeTrait` - The identifier for the group.
675    /// - `Capacity` - The capacity for the broadcast sender.
676    ///
677    /// # Returns
678    ///
679    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-group broadcast.
680    #[inline(always)]
681    fn point_to_group<B>(&self, key: &B, capacity: Capacity) -> BroadcastMapReceiver<Vec<u8>>
682    where
683        B: BroadcastTypeTrait,
684    {
685        self.subscribe_unwrap_or_insert(BroadcastType::PointToGroup(key.clone()), capacity)
686    }
687
688    /// Retrieves the current receiver count for a given broadcast type.
689    ///
690    /// # Type Parameters
691    ///
692    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
693    ///
694    /// # Arguments
695    ///
696    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
697    ///
698    /// # Returns
699    ///
700    /// - `ReceiverCount` - The number of active receivers for the broadcast type, or 0 if not found.
701    #[inline(always)]
702    pub fn receiver_count<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
703    where
704        B: BroadcastTypeTrait,
705    {
706        let key: String = BroadcastType::get_key(broadcast_type);
707        self.broadcast_map.receiver_count(&key).unwrap_or(0)
708    }
709
710    /// Calculates the receiver count before a connection is established.
711    ///
712    /// Ensures the count does not exceed the maximum allowed value minus one.
713    ///
714    /// # Type Parameters
715    ///
716    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
717    ///
718    /// # Arguments
719    ///
720    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
721    ///
722    /// # Returns
723    ///
724    /// - `ReceiverCount` - The receiver count after the connection is established.
725    #[inline(always)]
726    pub fn receiver_count_before_connected<B>(
727        &self,
728        broadcast_type: BroadcastType<B>,
729    ) -> ReceiverCount
730    where
731        B: BroadcastTypeTrait,
732    {
733        let count: ReceiverCount = self.receiver_count(broadcast_type);
734        count.clamp(0, ReceiverCount::MAX - 1) + 1
735    }
736
737    /// Calculates the receiver count after a connection is closed.
738    ///
739    /// Ensures the count does not go below 0.
740    ///
741    /// # Type Parameters
742    ///
743    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
744    ///
745    /// # Arguments
746    ///
747    /// - `BroadcastType<BroadcastTypeTrait>` - The broadcast type for which to get the receiver count.
748    ///
749    /// # Returns
750    ///
751    /// - `ReceiverCount` - The receiver count after the connection is closed.
752    #[inline(always)]
753    pub fn receiver_count_after_closed<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
754    where
755        B: BroadcastTypeTrait,
756    {
757        let count: ReceiverCount = self.receiver_count(broadcast_type);
758        count.clamp(1, ReceiverCount::MAX) - 1
759    }
760
761    /// Sends data to all active receivers for a given broadcast type.
762    ///
763    /// # Type Parameters
764    ///
765    /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
766    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
767    ///
768    /// # Arguments
769    ///
770    /// - `BroadcastType<BroadcastTypeTrait>` - The broadcast type to which to send the data.
771    /// - `Into<Vec<u8>>` - The data to send.
772    ///
773    /// # Returns
774    ///
775    /// - `Result<Option<ReceiverCount>, SendError<Vec<u8>>>` - A result indicating the success or failure of the send operation.
776    #[inline(always)]
777    pub fn try_send<T, B>(
778        &self,
779        broadcast_type: BroadcastType<B>,
780        data: T,
781    ) -> Result<Option<ReceiverCount>, SendError<Vec<u8>>>
782    where
783        T: Into<Vec<u8>>,
784        B: BroadcastTypeTrait,
785    {
786        let key: String = BroadcastType::get_key(broadcast_type);
787        self.broadcast_map.try_send(&key, data.into())
788    }
789
790    /// Sends data to all active receivers for a given broadcast type.
791    ///
792    /// This method panics if the send operation fails.
793    ///
794    /// # Type Parameters
795    ///
796    /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
797    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
798    ///
799    /// # Arguments
800    ///
801    /// - `BroadcastType<BroadcastTypeTrait>` - The broadcast type to which to send the data.
802    /// - `Into<Vec<u8>>` - The data to send.
803    ///
804    /// # Returns
805    ///
806    /// - `Option<ReceiverCount>` - The receiver count if the send operation succeeds.
807    ///
808    /// # Panics
809    ///
810    /// Panics if the send operation fails.
811    #[inline(always)]
812    pub fn send<T, B>(&self, broadcast_type: BroadcastType<B>, data: T) -> Option<ReceiverCount>
813    where
814        T: Into<Vec<u8>>,
815        B: BroadcastTypeTrait,
816    {
817        self.try_send(broadcast_type, data).unwrap()
818    }
819
820    /// Runs the WebSocket connection, handling incoming requests and outgoing messages.
821    ///
822    /// This asynchronous function continuously monitors for new WebSocket requests
823    /// and incoming broadcast messages, processing them according to the configured hooks.
824    ///
825    /// # Type Parameters
826    ///
827    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
828    ///
829    /// # Arguments
830    ///
831    /// - `WebSocketConfig<BroadcastTypeTrait>` - The WebSocket configuration containing the configuration for this WebSocket instance.
832    ///
833    /// # Panics
834    ///
835    /// Panics if the context in the WebSocket configuration is not set (i.e., it's the default context).
836    /// Panics if the broadcast type in the WebSocket configuration is `BroadcastType::Unknown`.
837    pub async fn run<B>(&self, websocket_config: WebSocketConfig<'_, B>)
838    where
839        B: BroadcastTypeTrait,
840    {
841        let capacity: Capacity = websocket_config.get_capacity();
842        let broadcast_type: BroadcastType<B> = websocket_config.get_broadcast_type().clone();
843        let connected_hook: ServerHookHandler = websocket_config.get_connected_hook().clone();
844        let sended_hook: ServerHookHandler = websocket_config.get_sended_hook().clone();
845        let request_hook: ServerHookHandler = websocket_config.get_request_hook().clone();
846        let closed_hook: ServerHookHandler = websocket_config.get_closed_hook().clone();
847        let WebSocketConfig {
848            stream,
849            context: ctx,
850            ..
851        } = websocket_config;
852        let mut receiver: Receiver<Vec<u8>> = match &broadcast_type {
853            BroadcastType::PointToPoint(key1, key2) => self.point_to_point(key1, key2, capacity),
854            BroadcastType::PointToGroup(key) => self.point_to_group(key, capacity),
855            BroadcastType::Unknown => panic!("BroadcastType must be PointToPoint or PointToGroup"),
856        };
857        let key: String = BroadcastType::get_key(broadcast_type);
858        if connected_hook(stream, ctx).await.is_reject() {
859            return;
860        }
861        let mut is_reject: bool;
862        loop {
863            tokio::select! {
864                request_res = stream.try_get_websocket_request() => {
865                    if let Ok(body) = request_res {
866                        ctx.get_mut_request().set_body(body);
867                        is_reject = request_hook(stream, ctx).await.is_reject();
868                    } else {
869                        is_reject = true;
870                        closed_hook(stream, ctx).await;
871                    }
872                    let body: ResponseBody = ctx.get_response().get_body().clone();
873                    let is_err: bool = self.broadcast_map.try_send(&key, body).is_err();
874                    if is_err || sended_hook(stream, ctx).await.is_reject() || is_reject {
875                        break;
876                    }
877                },
878                msg_res = receiver.recv() => {
879                    if let Ok(msg) = &msg_res {
880                        if stream.try_send_list(&WebSocketFrame::create_frame_list(msg)).await.is_ok() {
881                            continue;
882                        } else {
883                            break;
884                        }
885                    }
886                    break;
887                }
888            }
889        }
890        stream.set_closed(true);
891    }
892}