roopes_core/patterns/publisher_subscriber/
vec_publisher.rs

1//! Contains an implementation of [`Publisher`]
2//! which stores its [`Subscriber`]s in a [`Vec`].
3
4use super::{
5    AttachablePublisher,
6    DetachablePublisher,
7};
8use crate::prelude::*;
9use core::marker::PhantomData;
10use std::{
11    cell::RefCell,
12    fmt::Debug,
13};
14
15/// Implements a [`Publisher`] based on a [`Vec`]
16/// of [`Subscriber`]s. # Example
17/// ``` rust
18/// use roopes::prelude::*;
19/// use std::{
20///     cell::RefCell,
21///     rc::Rc,
22/// };
23///
24/// let has_run = Rc::new(RefCell::new(false));
25/// let mut publisher = publisher_subscriber::VecPublisher::default();
26/// let has_run_ext = has_run.clone();
27/// let heap_handler =
28///     handler::Heap::new(Box::new(handler::Lambda::new(move |v| {
29///         (*has_run_ext.borrow_mut()) = *v;
30///     })));
31/// let sub_handler: SubscribingHandler<_, _> = heap_handler.into();
32/// let subscriber =
33///     publisher_subscriber::heap::Subscriber::new(Box::new(sub_handler));
34/// publisher.attach(subscriber);
35/// assert!(!(*has_run.borrow()));
36/// publisher.publish(&true);
37/// assert!((*has_run.borrow()));
38/// ```
39pub struct VecPublisher<M, S>
40where
41    S: Subscriber<M>,
42{
43    listeners: Vec<S>,
44    _retain_types: PhantomData<M>,
45}
46
47/// An Error which occurs during detachment.
48#[derive(Debug)]
49pub enum DetachError
50{
51    /// The specified observer couldn't be found.
52    SubscriberNotFound,
53}
54
55impl<M, S> Debug for VecPublisher<M, S>
56where
57    S: Subscriber<M> + Debug,
58{
59    fn fmt(
60        &self,
61        f: &mut std::fmt::Formatter<'_>,
62    ) -> std::fmt::Result
63    {
64        f.debug_struct("VecPublisher")
65            .field("listeners", &self.listeners)
66            .finish()
67    }
68}
69
70impl<M, S> Default for VecPublisher<M, S>
71where
72    S: Subscriber<M>,
73{
74    fn default() -> Self
75    {
76        Self::new(Vec::default())
77    }
78}
79
80impl<M, S> VecPublisher<M, S>
81where
82    S: Subscriber<M>,
83{
84    /// Creates a new [`VecPublisher`] with the
85    /// given [`Vec`] of starting
86    /// [`Subscriber`]s.
87    #[must_use]
88    pub fn new(listeners: Vec<S>) -> VecPublisher<M, S>
89    {
90        VecPublisher {
91            listeners,
92            _retain_types: PhantomData,
93        }
94    }
95}
96
97impl<M, S> Publisher<M> for VecPublisher<M, S>
98where
99    S: Subscriber<M>,
100{
101    fn publish(
102        &self,
103        message: &M,
104    )
105    {
106        self.listeners.iter().for_each(|s| s.receive(message));
107    }
108}
109
110impl<M, S> DetachablePublisher<M, S, DetachError> for VecPublisher<M, S>
111where
112    S: Subscriber<M> + Eq,
113{
114    fn detach(
115        &mut self,
116        detach_subscriber: &S,
117    ) -> Result<(), DetachError>
118    {
119        let (i, _) = self
120            .listeners
121            .iter()
122            .enumerate()
123            .find(|(_, o)| o.eq(&detach_subscriber))
124            .ok_or(DetachError::SubscriberNotFound)?;
125
126        self.listeners.swap_remove(i);
127
128        Ok(())
129    }
130}
131
132impl<M, S> AttachablePublisher<M, S> for VecPublisher<M, S>
133where
134    S: Subscriber<M>,
135{
136    fn attach(
137        &mut self,
138        attach_subscriber: S,
139    )
140    {
141        self.listeners.push(attach_subscriber);
142    }
143}