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