roopes_core/patterns/observer/
vec_subject.rs

1//! Contains types which implement the Observer
2//! pattern via an internal [`Vec`].
3
4use super::{
5    AttachableSubject,
6    DetachableSubject,
7    Observer,
8    Subject,
9};
10use std::{
11    borrow::BorrowMut,
12    cell::RefCell,
13};
14
15/// Implements [`Subject`] backed by a [`Vec<T>`].
16/// If `T` implements [`Eq`],
17/// then [`DetachableSubject`] is also provided.
18/// [`AttachableSubject`] is always provided.
19///
20///  # Examples
21///  ``` rust
22/// use roopes::prelude::*;
23/// use std::{
24///     cell::RefCell,
25///     rc::Rc,
26/// };
27///
28/// let mut vs = observer::VecSubject::default();
29///
30/// let has_run = Rc::new(RefCell::new(false));
31/// {
32///     let has_run = has_run.clone();
33///
34///     let lc: ObservingCommand<_> =
35///         command::Heap::from(move
36/// || {             (*has_run.borrow_mut()) =
37/// true;         })
38///         .into();
39///
40///     vs.attach(lc);
41/// }
42///
43/// assert!(!(*has_run.borrow()));
44/// vs.notify();
45/// assert!((*has_run.borrow()));
46///  ```
47
48pub struct VecSubject<O>
49where
50    O: Observer,
51{
52    listeners: RefCell<Vec<O>>,
53}
54
55impl<O> VecSubject<O>
56where
57    O: Observer,
58{
59    /// Creates a new [`VecSubject`] with an
60    /// existing list of listeners.
61    /// [`VecSubject::default`] is probably
62    /// preferable in most circumstances.
63    #[must_use]
64    pub fn new(listeners: RefCell<Vec<O>>) -> VecSubject<O>
65    {
66        VecSubject { listeners }
67    }
68}
69
70impl<O> AttachableSubject<O> for VecSubject<O>
71where
72    O: Observer,
73{
74    fn attach(
75        &mut self,
76        attach_observer: O,
77    )
78    {
79        self.listeners.borrow_mut().push(attach_observer);
80    }
81}
82
83/// An Error which occurs during detachment.
84#[derive(Debug)]
85pub enum DetachError
86{
87    /// The specified observer couldn't be found.
88    ObserverNotFound,
89}
90impl<O> DetachableSubject<O, DetachError> for VecSubject<O>
91where
92    O: Observer + Eq,
93{
94    fn detach(
95        &mut self,
96        detach_observer: &O,
97    ) -> Result<(), DetachError>
98    {
99        let (i, _) = self
100            .listeners
101            .borrow()
102            .iter()
103            .enumerate()
104            .find(|(_, o)| o.eq(&detach_observer))
105            .ok_or(DetachError::ObserverNotFound)?;
106
107        self.listeners.borrow_mut().swap_remove(i);
108
109        Ok(())
110    }
111}
112
113impl<O> Default for VecSubject<O>
114where
115    O: Observer,
116{
117    fn default() -> Self
118    {
119        Self::new(RefCell::default())
120    }
121}
122
123impl<O> Subject for VecSubject<O>
124where
125    O: Observer,
126{
127    fn notify(&self)
128    {
129        self.listeners.borrow().iter().for_each(Observer::notify);
130    }
131}