Skip to main content

hyperlane_plugin_websocket/
impl.rs

1use super::*;
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/// Implements `BroadcastTypeTrait` for `&u64`.
148///
149/// This allows references to `u64` to be used as a broadcast identifier.
150impl BroadcastTypeTrait for &u64 {}
151
152/// Implements `BroadcastTypeTrait` for `&u128`.
153///
154/// This allows references to `u128` to be used as a broadcast identifier.
155impl BroadcastTypeTrait for &u128 {}
156
157/// Implements `BroadcastTypeTrait` for `&usize`.
158///
159/// This allows references to `usize` to be used as a broadcast identifier.
160impl BroadcastTypeTrait for &usize {}
161
162/// Implements `BroadcastTypeTrait` for `&f32`.
163///
164/// This allows references to `f32` to be used as a broadcast identifier.
165impl BroadcastTypeTrait for &f32 {}
166
167/// Implements `BroadcastTypeTrait` for `&f64`.
168///
169/// This allows references to `f64` to be used as a broadcast identifier.
170impl BroadcastTypeTrait for &f64 {}
171
172/// Implements `BroadcastTypeTrait` for `&IpAddr`.
173///
174/// This allows references to `IpAddr` to be used as a broadcast identifier.
175impl BroadcastTypeTrait for &IpAddr {}
176
177/// Implements `BroadcastTypeTrait` for `&Ipv4Addr`.
178///
179/// This allows references to `Ipv4Addr` to be used as a broadcast identifier.
180impl BroadcastTypeTrait for &Ipv4Addr {}
181
182/// Implements `BroadcastTypeTrait` for `&Ipv6Addr`.
183///
184/// This allows references to `Ipv6Addr` to be used as a broadcast identifier.
185impl BroadcastTypeTrait for &Ipv6Addr {}
186
187/// Implements `BroadcastTypeTrait` for `&SocketAddr`.
188///
189/// This allows references to `SocketAddr` to be used as a broadcast identifier.
190impl BroadcastTypeTrait for &SocketAddr {}
191
192/// Implements `BroadcastTypeTrait` for `&NonZeroU8`.
193///
194/// This allows references to `NonZeroU8` to be used as a broadcast identifier.
195impl BroadcastTypeTrait for &NonZeroU8 {}
196
197/// Implements `BroadcastTypeTrait` for `&NonZeroU16`.
198///
199/// This allows references to `NonZeroU16` to be used as a broadcast identifier.
200impl BroadcastTypeTrait for &NonZeroU16 {}
201
202/// Implements `BroadcastTypeTrait` for `&NonZeroU32`.
203///
204/// This allows references to `NonZeroU32` to be used as a broadcast identifier.
205impl BroadcastTypeTrait for &NonZeroU32 {}
206
207/// Implements `BroadcastTypeTrait` for `&NonZeroU64`.
208///
209/// This allows references to `NonZeroU64` to be used as a broadcast identifier.
210impl BroadcastTypeTrait for &NonZeroU64 {}
211
212/// Implements `BroadcastTypeTrait` for `&NonZeroU128`.
213///
214/// This allows references to `NonZeroU128` to be used as a broadcast identifier.
215impl BroadcastTypeTrait for &NonZeroU128 {}
216
217/// Implements `BroadcastTypeTrait` for `&NonZeroUsize`.
218///
219/// This allows references to `NonZeroUsize` to be used as a broadcast identifier.
220impl BroadcastTypeTrait for &NonZeroUsize {}
221
222/// Implements `BroadcastTypeTrait` for `&NonZeroI8`.
223///
224/// This allows references to `NonZeroI8` to be used as a broadcast identifier.
225impl BroadcastTypeTrait for &NonZeroI8 {}
226
227/// Implements `BroadcastTypeTrait` for `&NonZeroI16`.
228///
229/// This allows references to `NonZeroI16` to be used as a broadcast identifier.
230impl BroadcastTypeTrait for &NonZeroI16 {}
231
232/// Implements `BroadcastTypeTrait` for `&NonZeroI32`.
233///
234/// This allows references to `NonZeroI32` to be used as a broadcast identifier.
235impl BroadcastTypeTrait for &NonZeroI32 {}
236
237/// Implements `BroadcastTypeTrait` for `&NonZeroI64`.
238///
239/// This allows references to `NonZeroI64` to be used as a broadcast identifier.
240impl BroadcastTypeTrait for &NonZeroI64 {}
241
242/// Implements `BroadcastTypeTrait` for `&NonZeroI128`.
243///
244/// This allows references to `NonZeroI128` to be used as a broadcast identifier.
245impl BroadcastTypeTrait for &NonZeroI128 {}
246
247/// Implements `BroadcastTypeTrait` for `&NonZeroIsize`.
248///
249/// This allows references to `NonZeroIsize` to be used as a broadcast identifier.
250impl BroadcastTypeTrait for &NonZeroIsize {}
251
252/// Implements `BroadcastTypeTrait` for `&Infallible`.
253///
254/// This allows references to `Infallible` to be used as a broadcast identifier.
255impl BroadcastTypeTrait for &Infallible {}
256
257/// Implements the `Default` trait for `BroadcastType`.
258///
259/// The default value is `BroadcastType::Unknown`.
260///
261/// # Type Parameters
262///
263/// - `BroadcastTypeTrait`: The type parameter for `BroadcastType`, which must implement `BroadcastTypeTrait`.
264impl<B> Default for BroadcastType<B>
265where
266    B: BroadcastTypeTrait,
267{
268    /// Returns the default `BroadcastType`, which is `BroadcastType::Unknown`.
269    #[inline(always)]
270    fn default() -> Self {
271        BroadcastType::Unknown
272    }
273}
274
275impl<B> BroadcastType<B>
276where
277    B: BroadcastTypeTrait,
278{
279    /// Generates a unique key string for a given broadcast type.
280    ///
281    /// For point-to-point types, the keys are sorted to ensure consistent key generation
282    /// regardless of the order of the input keys.
283    ///
284    /// # Arguments
285    ///
286    /// - `BroadcastType<B>` - The broadcast type for which to generate the key.
287    ///
288    /// # Returns
289    ///
290    /// - `String` - The unique key string for the broadcast type.
291    #[inline(always)]
292    pub fn get_key(broadcast_type: BroadcastType<B>) -> String {
293        match broadcast_type {
294            BroadcastType::PointToPoint(key1, key2) => {
295                let (first_key, second_key) = if key1 <= key2 {
296                    (key1, key2)
297                } else {
298                    (key2, key1)
299                };
300                format!(
301                    "{}-{}-{}",
302                    POINT_TO_POINT_KEY,
303                    first_key.to_string(),
304                    second_key.to_string()
305                )
306            }
307            BroadcastType::PointToGroup(key) => {
308                format!("{}-{}", POINT_TO_GROUP_KEY, key.to_string())
309            }
310            BroadcastType::Unknown => String::new(),
311        }
312    }
313}
314
315impl<'a, B> WebSocketConfig<'a, B>
316where
317    B: BroadcastTypeTrait,
318{
319    /// Creates a new WebSocket configuration with the given context.
320    ///
321    /// # Arguments
322    ///
323    /// - `&'a mut Stream` - The stream object serving this WebSocket.
324    /// - `&'a mut Context` - The context object to associate with the WebSocket.
325    ///
326    /// # Returns
327    ///
328    /// - `WebSocketConfig<B>` - A new WebSocket configuration instance.
329    #[inline(always)]
330    pub fn new(stream: &'a mut Stream, context: &'a mut Context) -> Self {
331        Self {
332            stream,
333            context,
334            capacity: DEFAULT_BROADCAST_SENDER_CAPACITY,
335            broadcast_type: BroadcastType::default(),
336            connected_hook: Hook::default_handler(),
337            request_hook: Hook::default_handler(),
338            sended_hook: Hook::default_handler(),
339            closed_hook: Hook::default_handler(),
340        }
341    }
342}
343
344impl<'a, B> WebSocketConfig<'a, B>
345where
346    B: BroadcastTypeTrait,
347{
348    /// Sets the capacity for the broadcast sender.
349    ///
350    /// # Arguments
351    ///
352    /// - `Capacity` - The desired capacity.
353    ///
354    /// # Returns
355    ///
356    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
357    #[inline(always)]
358    pub fn set_capacity(mut self, capacity: Capacity) -> Self {
359        self.capacity = capacity;
360        self
361    }
362
363    /// Sets the context for the WebSocket connection.
364    ///
365    /// # Arguments
366    ///
367    /// - `&'a mut Context` - The context object to associate with the WebSocket.
368    ///
369    /// # Returns
370    ///
371    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
372    #[inline(always)]
373    pub fn set_context(mut self, context: &'a mut Context) -> Self {
374        self.context = context;
375        self
376    }
377
378    /// Sets the broadcast type for the WebSocket connection.
379    ///
380    /// # Arguments
381    ///
382    /// - `BroadcastType<B>` - The broadcast type to use for this WebSocket.
383    ///
384    /// # Returns
385    ///
386    /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
387    #[inline(always)]
388    pub fn set_broadcast_type(mut self, broadcast_type: BroadcastType<B>) -> Self {
389        self.broadcast_type = broadcast_type;
390        self
391    }
392
393    /// Sets the connected hook handler.
394    ///
395    /// This hook is executed when the WebSocket connection is established.
396    ///
397    /// # Type Parameters
398    ///
399    /// - `S`: The hook type, which must implement `ServerHook`.
400    ///
401    /// # Returns
402    ///
403    /// The modified `WebSocketConfig` instance.
404    ///
405    /// # Examples
406    ///
407    /// ```rust,ignore
408    /// struct MyConnectedHook;
409    /// impl ServerHook for MyConnectedHook {
410    ///     async fn new(_ctx: &Context) -> Self { Self }
411    ///     async fn handle(self, ctx: &Context) { /* ... */ }
412    /// }
413    ///
414    /// let config = WebSocketConfig::new()
415    ///     .set_connected_hook::<MyConnectedHook>();
416    /// ```
417    #[inline(always)]
418    pub fn set_connected_hook<S>(mut self) -> Self
419    where
420        S: ServerHook,
421    {
422        self.connected_hook = Hook::factory::<S>();
423        self
424    }
425
426    /// Sets the request hook handler.
427    ///
428    /// This hook is executed when a new request is received on the WebSocket.
429    ///
430    /// # Type Parameters
431    ///
432    /// - `S`: The hook type, which must implement `ServerHook`.
433    ///
434    /// # Returns
435    ///
436    /// The modified `WebSocketConfig` instance.
437    ///
438    /// # Examples
439    ///
440    /// ```rust,ignore
441    /// struct MyRequestHook;
442    /// impl ServerHook for MyRequestHook {
443    ///     async fn new(_ctx: &Context) -> Self { Self }
444    ///     async fn handle(self, ctx: &Context) { /* ... */ }
445    /// }
446    ///
447    /// let config = WebSocketConfig::new()
448    ///     .set_request_hook::<MyRequestHook>();
449    /// ```
450    #[inline(always)]
451    pub fn set_request_hook<S>(mut self) -> Self
452    where
453        S: ServerHook,
454    {
455        self.request_hook = Hook::factory::<S>();
456        self
457    }
458
459    /// Sets the sended hook handler.
460    ///
461    /// This hook is executed after a message has been successfully sent over the WebSocket.
462    ///
463    /// # Type Parameters
464    ///
465    /// - `S`: The hook type, which must implement `ServerHook`.
466    ///
467    /// # Returns
468    ///
469    /// The modified `WebSocketConfig` instance.
470    ///
471    /// # Examples
472    ///
473    /// ```rust,ignore
474    /// struct MySendedHook;
475    /// impl ServerHook for MySendedHook {
476    ///     async fn new(_ctx: &Context) -> Self { Self }
477    ///     async fn handle(self, ctx: &Context) { /* ... */ }
478    /// }
479    ///
480    /// let config = WebSocketConfig::new()
481    ///     .set_sended_hook::<MySendedHook>();
482    /// ```
483    #[inline(always)]
484    pub fn set_sended_hook<S>(mut self) -> Self
485    where
486        S: ServerHook,
487    {
488        self.sended_hook = Hook::factory::<S>();
489        self
490    }
491
492    /// Sets the closed hook handler.
493    ///
494    /// This hook is executed when the WebSocket connection is closed.
495    ///
496    /// # Type Parameters
497    ///
498    /// - `S`: The hook type, which must implement `ServerHook`.
499    ///
500    /// # Returns
501    ///
502    /// The modified `WebSocketConfig` instance.
503    ///
504    /// # Examples
505    ///
506    /// ```rust,ignore
507    /// struct MyClosedHook;
508    /// impl ServerHook for MyClosedHook {
509    ///     async fn new(_ctx: &Context) -> Self { Self }
510    ///     async fn handle(self, ctx: &Context) { /* ... */ }
511    /// }
512    ///
513    /// let config = WebSocketConfig::new()
514    ///     .set_closed_hook::<MyClosedHook>();
515    /// ```
516    #[inline(always)]
517    pub fn set_closed_hook<S>(mut self) -> Self
518    where
519        S: ServerHook,
520    {
521        self.closed_hook = Hook::factory::<S>();
522        self
523    }
524}
525
526impl WebSocket {
527    /// Creates a new WebSocket instance.
528    ///
529    /// Initializes with a default broadcast map.
530    ///
531    /// # Returns
532    ///
533    /// - `WebSocket` - A new WebSocket instance.
534    #[inline(always)]
535    pub fn new() -> Self {
536        Self::default()
537    }
538
539    /// Subscribes to a broadcast type or inserts a new one if it doesn't exist.
540    ///
541    /// # Type Parameters
542    ///
543    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
544    ///
545    /// # Arguments
546    ///
547    /// - `BroadcastType<B>` - The broadcast type to subscribe to.
548    /// - `Capacity` - The capacity for the broadcast sender if a new one is inserted.
549    ///
550    /// # Returns
551    ///
552    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the specified broadcast type.
553    #[inline(always)]
554    fn subscribe_unwrap_or_insert<B>(
555        &self,
556        broadcast_type: BroadcastType<B>,
557        capacity: Capacity,
558    ) -> BroadcastMapReceiver<Vec<u8>>
559    where
560        B: BroadcastTypeTrait,
561    {
562        let key: String = BroadcastType::get_key(broadcast_type);
563        self.get_broadcast_map().subscribe_or_insert(&key, capacity)
564    }
565
566    /// Subscribes to a point-to-point broadcast.
567    ///
568    /// # Type Parameters
569    ///
570    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
571    ///
572    /// # Arguments
573    ///
574    /// - `&B` - The first identifier for the point-to-point communication.
575    /// - `&B` - The second identifier for the point-to-point communication.
576    /// - `Capacity` - The capacity for the broadcast sender.
577    ///
578    /// # Returns
579    ///
580    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-point broadcast.
581    #[inline(always)]
582    fn point_to_point<B>(
583        &self,
584        key1: &B,
585        key2: &B,
586        capacity: Capacity,
587    ) -> BroadcastMapReceiver<Vec<u8>>
588    where
589        B: BroadcastTypeTrait,
590    {
591        self.subscribe_unwrap_or_insert(
592            BroadcastType::PointToPoint(key1.clone(), key2.clone()),
593            capacity,
594        )
595    }
596
597    /// Subscribes to a point-to-group broadcast.
598    ///
599    /// # Type Parameters
600    ///
601    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
602    ///
603    /// # Arguments
604    ///
605    /// - `&B` - The identifier for the group.
606    /// - `Capacity` - The capacity for the broadcast sender.
607    ///
608    /// # Returns
609    ///
610    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-group broadcast.
611    #[inline(always)]
612    fn point_to_group<B>(&self, key: &B, capacity: Capacity) -> BroadcastMapReceiver<Vec<u8>>
613    where
614        B: BroadcastTypeTrait,
615    {
616        self.subscribe_unwrap_or_insert(BroadcastType::PointToGroup(key.clone()), capacity)
617    }
618
619    /// Retrieves the current receiver count for a given broadcast type.
620    ///
621    /// # Type Parameters
622    ///
623    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
624    ///
625    /// # Arguments
626    ///
627    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
628    ///
629    /// # Returns
630    ///
631    /// - `ReceiverCount` - The number of active receivers for the broadcast type, or 0 if not found.
632    #[inline(always)]
633    pub fn receiver_count<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
634    where
635        B: BroadcastTypeTrait,
636    {
637        let key: String = BroadcastType::get_key(broadcast_type);
638        self.get_broadcast_map().receiver_count(&key).unwrap_or(0)
639    }
640
641    /// Calculates the receiver count before a connection is established.
642    ///
643    /// Ensures the count does not exceed the maximum allowed value minus one.
644    ///
645    /// # Type Parameters
646    ///
647    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
648    ///
649    /// # Arguments
650    ///
651    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
652    ///
653    /// # Returns
654    ///
655    /// - `ReceiverCount` - The receiver count after the connection is established.
656    #[inline(always)]
657    pub fn receiver_count_before_connected<B>(
658        &self,
659        broadcast_type: BroadcastType<B>,
660    ) -> ReceiverCount
661    where
662        B: BroadcastTypeTrait,
663    {
664        let count: ReceiverCount = self.receiver_count(broadcast_type);
665        count.clamp(0, ReceiverCount::MAX - 1) + 1
666    }
667
668    /// Calculates the receiver count after a connection is closed.
669    ///
670    /// Ensures the count does not go below 0.
671    ///
672    /// # Type Parameters
673    ///
674    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
675    ///
676    /// # Arguments
677    ///
678    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
679    ///
680    /// # Returns
681    ///
682    /// - `ReceiverCount` - The receiver count after the connection is closed.
683    #[inline(always)]
684    pub fn receiver_count_after_closed<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
685    where
686        B: BroadcastTypeTrait,
687    {
688        let count: ReceiverCount = self.receiver_count(broadcast_type);
689        count.clamp(1, ReceiverCount::MAX) - 1
690    }
691
692    /// Sends data to all active receivers for a given broadcast type.
693    ///
694    /// # Type Parameters
695    ///
696    /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
697    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
698    ///
699    /// # Arguments
700    ///
701    /// - `BroadcastType<B>` - The broadcast type to which to send the data.
702    /// - `T` - The data to send.
703    ///
704    /// # Returns
705    ///
706    /// - `Result<Option<ReceiverCount>, SendError<Vec<u8>>>` - A result indicating the success or failure of the send operation.
707    #[inline(always)]
708    pub fn try_send<T, B>(
709        &self,
710        broadcast_type: BroadcastType<B>,
711        data: T,
712    ) -> Result<Option<ReceiverCount>, SendError<Vec<u8>>>
713    where
714        T: Into<Vec<u8>>,
715        B: BroadcastTypeTrait,
716    {
717        let key: String = BroadcastType::get_key(broadcast_type);
718        self.get_broadcast_map().try_send(&key, data.into())
719    }
720
721    /// Sends data to all active receivers for a given broadcast type.
722    ///
723    /// This method panics if the send operation fails.
724    ///
725    /// # Type Parameters
726    ///
727    /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
728    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
729    ///
730    /// # Arguments
731    ///
732    /// - `BroadcastType<B>` - The broadcast type to which to send the data.
733    /// - `T` - The data to send.
734    ///
735    /// # Returns
736    ///
737    /// - `Option<ReceiverCount>` - The receiver count if the send operation succeeds.
738    ///
739    /// # Panics
740    ///
741    /// Panics if the send operation fails.
742    #[inline(always)]
743    pub fn send<T, B>(&self, broadcast_type: BroadcastType<B>, data: T) -> Option<ReceiverCount>
744    where
745        T: Into<Vec<u8>>,
746        B: BroadcastTypeTrait,
747    {
748        self.try_send(broadcast_type, data).unwrap()
749    }
750
751    /// Runs the WebSocket connection, handling incoming requests and outgoing messages.
752    ///
753    /// This asynchronous function continuously monitors for new WebSocket requests
754    /// and incoming broadcast messages, processing them according to the configured hooks.
755    ///
756    /// # Type Parameters
757    ///
758    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
759    ///
760    /// # Arguments
761    ///
762    /// - `WebSocketConfig<'_, B>` - The WebSocket configuration containing the configuration for this WebSocket instance.
763    ///
764    /// # Panics
765    ///
766    /// Panics if the context in the WebSocket configuration is not set (i.e., it's the default context).
767    /// Panics if the broadcast type in the WebSocket configuration is `BroadcastType::Unknown`.
768    pub async fn run<B>(&self, websocket_config: WebSocketConfig<'_, B>)
769    where
770        B: BroadcastTypeTrait,
771    {
772        let capacity: Capacity = websocket_config.get_capacity();
773        let broadcast_type: BroadcastType<B> = websocket_config.get_broadcast_type().clone();
774        let connected_hook: ServerHookHandler = websocket_config.get_connected_hook().clone();
775        let sended_hook: ServerHookHandler = websocket_config.get_sended_hook().clone();
776        let request_hook: ServerHookHandler = websocket_config.get_request_hook().clone();
777        let closed_hook: ServerHookHandler = websocket_config.get_closed_hook().clone();
778        let WebSocketConfig {
779            stream,
780            context: ctx,
781            ..
782        } = websocket_config;
783        let mut receiver: Receiver<Vec<u8>> = match &broadcast_type {
784            BroadcastType::PointToPoint(key1, key2) => self.point_to_point(key1, key2, capacity),
785            BroadcastType::PointToGroup(key) => self.point_to_group(key, capacity),
786            BroadcastType::Unknown => panic!("BroadcastType must be PointToPoint or PointToGroup"),
787        };
788        let key: String = BroadcastType::get_key(broadcast_type);
789        if connected_hook(stream, ctx).await.is_reject() {
790            return;
791        }
792        let mut is_reject: bool;
793        loop {
794            tokio::select! {
795                request_res = stream.try_get_websocket_request() => {
796                    if let Ok(body) = request_res {
797                        ctx.get_mut_request().set_body(body);
798                        is_reject = request_hook(stream, ctx).await.is_reject();
799                    } else {
800                        is_reject = true;
801                        closed_hook(stream, ctx).await;
802                    }
803                    let body: ResponseBody = ctx.get_response().get_body().clone();
804                    let is_err: bool = self.get_broadcast_map().try_send(&key, body).is_err();
805                    if is_err || sended_hook(stream, ctx).await.is_reject() || is_reject {
806                        break;
807                    }
808                },
809                msg_res = receiver.recv() => {
810                    if let Ok(msg) = &msg_res {
811                        if stream.try_send_list(&WebSocketFrame::create_frame_list(msg)).await.is_ok() {
812                            continue;
813                        } else {
814                            break;
815                        }
816                    }
817                    break;
818                }
819            }
820        }
821        stream.set_closed(true);
822    }
823}