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