hyperlane_plugin_websocket/
impl.rs

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