maiko/subscribe.rs
1use std::{collections::HashSet, marker::PhantomData};
2
3use crate::{Event, Topic, internal::Subscription};
4
5/// Specifies which topics an actor subscribes to.
6///
7/// Use the static constructors to create subscriptions:
8///
9/// - [`Subscribe::all()`] - receive events on all topics (e.g., monitoring actors)
10/// - [`Subscribe::none()`] - receive no events (e.g., pure event producers)
11/// - [`Subscribe::to`] - receive events on specific topics
12///
13/// For convenience, `&[T]` converts to `Subscribe` automatically:
14///
15/// ```ignore
16/// // These are equivalent:
17/// sup.add_actor("a", factory, &[Topic::Data])?;
18/// sup.add_actor("a", factory, Subscribe::to([Topic::Data]))?;
19/// ```
20pub struct Subscribe<E: Event, T: Topic<E>>(
21 pub(crate) Subscription<T>,
22 PhantomData<fn() -> E>, // invariant over E
23);
24
25impl<E: Event, T: Topic<E>> Subscribe<E, T> {
26 /// Subscribe to all topics.
27 ///
28 /// Useful for monitoring actors that need to observe all events.
29 pub fn all() -> Self {
30 Subscribe(Subscription::All, PhantomData)
31 }
32
33 /// Subscribe to no topics.
34 ///
35 /// Useful for actors that only produce events and don't need to receive any.
36 pub fn none() -> Self {
37 Subscribe(Subscription::None, PhantomData)
38 }
39
40 /// Subscribe to specific topics.
41 ///
42 /// Accepts any iterator of topics:
43 /// ```ignore
44 /// Subscribe::to([Topic::A, Topic::B])
45 /// Subscribe::to(vec![Topic::A])
46 /// Subscribe::to(&[Topic::A, Topic::B])
47 /// ```
48 pub fn to(topics: impl IntoIterator<Item = T>) -> Self {
49 let set = HashSet::from_iter(topics);
50 Subscribe(Subscription::Topics(set), PhantomData)
51 }
52}
53
54impl<E: Event, T: Topic<E>> From<&[T]> for Subscribe<E, T> {
55 fn from(topics: &[T]) -> Self {
56 Subscribe::to(topics.iter().cloned())
57 }
58}
59
60impl<E: Event, T: Topic<E>, const N: usize> From<[T; N]> for Subscribe<E, T> {
61 fn from(topics: [T; N]) -> Self {
62 Subscribe::to(topics)
63 }
64}
65
66impl<E: Event, T: Topic<E>, const N: usize> From<&[T; N]> for Subscribe<E, T> {
67 fn from(topics: &[T; N]) -> Self {
68 Subscribe::to(topics.iter().cloned())
69 }
70}