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
526/// Inherent implementation of [`WebSocket`].
527impl WebSocket {
528    /// Creates a new WebSocket instance.
529    ///
530    /// Initializes with a default broadcast map.
531    ///
532    /// # Returns
533    ///
534    /// - `WebSocket` - A new WebSocket instance.
535    #[inline(always)]
536    pub fn new() -> Self {
537        Self::default()
538    }
539
540    /// Subscribes to a broadcast type or inserts a new one if it doesn't exist.
541    ///
542    /// # Type Parameters
543    ///
544    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
545    ///
546    /// # Arguments
547    ///
548    /// - `BroadcastType<B>` - The broadcast type to subscribe to.
549    /// - `Capacity` - The capacity for the broadcast sender if a new one is inserted.
550    ///
551    /// # Returns
552    ///
553    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the specified broadcast type.
554    #[inline(always)]
555    fn subscribe_unwrap_or_insert<B>(
556        &self,
557        broadcast_type: BroadcastType<B>,
558        capacity: Capacity,
559    ) -> BroadcastMapReceiver<Vec<u8>>
560    where
561        B: BroadcastTypeTrait,
562    {
563        let key: String = BroadcastType::get_key(broadcast_type);
564        self.get_broadcast_map().subscribe_or_insert(&key, capacity)
565    }
566
567    /// Subscribes to a point-to-point broadcast.
568    ///
569    /// # Type Parameters
570    ///
571    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
572    ///
573    /// # Arguments
574    ///
575    /// - `&B` - The first identifier for the point-to-point communication.
576    /// - `&B` - The second identifier for the point-to-point communication.
577    /// - `Capacity` - The capacity for the broadcast sender.
578    ///
579    /// # Returns
580    ///
581    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-point broadcast.
582    #[inline(always)]
583    fn point_to_point<B>(
584        &self,
585        key1: &B,
586        key2: &B,
587        capacity: Capacity,
588    ) -> BroadcastMapReceiver<Vec<u8>>
589    where
590        B: BroadcastTypeTrait,
591    {
592        self.subscribe_unwrap_or_insert(
593            BroadcastType::PointToPoint(key1.clone(), key2.clone()),
594            capacity,
595        )
596    }
597
598    /// Subscribes to a point-to-group broadcast.
599    ///
600    /// # Type Parameters
601    ///
602    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
603    ///
604    /// # Arguments
605    ///
606    /// - `&B` - The identifier for the group.
607    /// - `Capacity` - The capacity for the broadcast sender.
608    ///
609    /// # Returns
610    ///
611    /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-group broadcast.
612    #[inline(always)]
613    fn point_to_group<B>(&self, key: &B, capacity: Capacity) -> BroadcastMapReceiver<Vec<u8>>
614    where
615        B: BroadcastTypeTrait,
616    {
617        self.subscribe_unwrap_or_insert(BroadcastType::PointToGroup(key.clone()), capacity)
618    }
619
620    /// Retrieves the current receiver count for a given broadcast type.
621    ///
622    /// # Type Parameters
623    ///
624    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
625    ///
626    /// # Arguments
627    ///
628    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
629    ///
630    /// # Returns
631    ///
632    /// - `ReceiverCount` - The number of active receivers for the broadcast type, or 0 if not found.
633    #[inline(always)]
634    pub fn receiver_count<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
635    where
636        B: BroadcastTypeTrait,
637    {
638        let key: String = BroadcastType::get_key(broadcast_type);
639        self.get_broadcast_map().receiver_count(&key).unwrap_or(0)
640    }
641
642    /// Calculates the receiver count before a connection is established.
643    ///
644    /// Ensures the count does not exceed the maximum allowed value minus one.
645    ///
646    /// # Type Parameters
647    ///
648    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
649    ///
650    /// # Arguments
651    ///
652    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
653    ///
654    /// # Returns
655    ///
656    /// - `ReceiverCount` - The receiver count after the connection is established.
657    #[inline(always)]
658    pub fn receiver_count_before_connected<B>(
659        &self,
660        broadcast_type: BroadcastType<B>,
661    ) -> ReceiverCount
662    where
663        B: BroadcastTypeTrait,
664    {
665        let count: ReceiverCount = self.receiver_count(broadcast_type);
666        count.clamp(0, ReceiverCount::MAX - 1) + 1
667    }
668
669    /// Calculates the receiver count after a connection is closed.
670    ///
671    /// Ensures the count does not go below 0.
672    ///
673    /// # Type Parameters
674    ///
675    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
676    ///
677    /// # Arguments
678    ///
679    /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
680    ///
681    /// # Returns
682    ///
683    /// - `ReceiverCount` - The receiver count after the connection is closed.
684    #[inline(always)]
685    pub fn receiver_count_after_closed<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
686    where
687        B: BroadcastTypeTrait,
688    {
689        let count: ReceiverCount = self.receiver_count(broadcast_type);
690        count.clamp(1, ReceiverCount::MAX) - 1
691    }
692
693    /// Sends data to all active receivers for a given broadcast type.
694    ///
695    /// # Type Parameters
696    ///
697    /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
698    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
699    ///
700    /// # Arguments
701    ///
702    /// - `BroadcastType<B>` - The broadcast type to which to send the data.
703    /// - `T` - The data to send.
704    ///
705    /// # Returns
706    ///
707    /// - `Result<Option<ReceiverCount>, SendError<Vec<u8>>>` - A result indicating the success or failure of the send operation.
708    #[inline(always)]
709    pub fn try_send<T, B>(
710        &self,
711        broadcast_type: BroadcastType<B>,
712        data: T,
713    ) -> Result<Option<ReceiverCount>, SendError<Vec<u8>>>
714    where
715        T: Into<Vec<u8>>,
716        B: BroadcastTypeTrait,
717    {
718        let key: String = BroadcastType::get_key(broadcast_type);
719        self.get_broadcast_map().try_send(&key, data.into())
720    }
721
722    /// Sends data to all active receivers for a given broadcast type.
723    ///
724    /// This method panics if the send operation fails.
725    ///
726    /// # Type Parameters
727    ///
728    /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
729    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
730    ///
731    /// # Arguments
732    ///
733    /// - `BroadcastType<B>` - The broadcast type to which to send the data.
734    /// - `T` - The data to send.
735    ///
736    /// # Returns
737    ///
738    /// - `Option<ReceiverCount>` - The receiver count if the send operation succeeds.
739    ///
740    /// # Panics
741    ///
742    /// Panics if the send operation fails.
743    #[inline(always)]
744    pub fn send<T, B>(&self, broadcast_type: BroadcastType<B>, data: T) -> Option<ReceiverCount>
745    where
746        T: Into<Vec<u8>>,
747        B: BroadcastTypeTrait,
748    {
749        self.try_send(broadcast_type, data).unwrap()
750    }
751
752    /// Runs the WebSocket connection, handling incoming requests and outgoing messages.
753    ///
754    /// This asynchronous function continuously monitors for new WebSocket requests
755    /// and incoming broadcast messages, processing them according to the configured hooks.
756    ///
757    /// # Type Parameters
758    ///
759    /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
760    ///
761    /// # Arguments
762    ///
763    /// - `WebSocketConfig<'_, B>` - The WebSocket configuration containing the configuration for this WebSocket instance.
764    ///
765    /// # Panics
766    ///
767    /// Panics if the context in the WebSocket configuration is not set (i.e., it's the default context).
768    /// Panics if the broadcast type in the WebSocket configuration is `BroadcastType::Unknown`.
769    pub async fn run<B>(&self, websocket_config: WebSocketConfig<'_, B>)
770    where
771        B: BroadcastTypeTrait,
772    {
773        let WebSocketConfig {
774            stream,
775            context: ctx,
776            capacity,
777            broadcast_type,
778            connected_hook,
779            request_hook,
780            sended_hook,
781            closed_hook,
782        }: WebSocketConfig<'_, B> = 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}