hyperlane_plugin_websocket/websocket/
impl.rs

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