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