output_tracker/inner_subject/
mod.rs

1use crate::inner_tracker::CelledTracker;
2use crate::tracker_handle::TrackerHandle;
3use std::marker::PhantomData;
4use std::ops::{Deref, DerefMut};
5use std::slice;
6
7pub trait CelledSubject<M, T> {
8    type Inner<'a>: Deref<Target = BasicSubject<M, T>>
9    where
10        Self: 'a;
11    type InnerMut<'a>: DerefMut<Target = BasicSubject<M, T>>
12    where
13        Self: 'a;
14    type Error: std::error::Error;
15
16    fn subject(&self) -> Result<Self::Inner<'_>, Self::Error>;
17
18    fn subject_mut(&self) -> Result<Self::InnerMut<'_>, Self::Error>;
19
20    fn add_tracker(&self, tracker: T) -> Result<TrackerHandle, Self::Error>
21    where
22        T: CelledTracker<M>,
23    {
24        self.subject_mut()
25            .map(|mut subject| subject.add_tracker(tracker))
26    }
27
28    fn remove_tracker(&self, tracker: TrackerHandle) -> Result<(), Self::Error> {
29        self.subject_mut()
30            .map(|mut subject| subject.remove_tracker(tracker))
31    }
32
33    fn emit(&self, data: M) -> Result<(), Self::Error>
34    where
35        M: Clone,
36        T: CelledTracker<M>,
37        Self::Error: From<<T as CelledTracker<M>>::Error>,
38    {
39        for tracker in self.subject()?.trackers() {
40            tracker.track(data.clone())?;
41        }
42        Ok(())
43    }
44}
45
46#[derive(Debug)]
47pub struct BasicSubject<M, T> {
48    _data: PhantomData<M>,
49    trackers: Vec<(TrackerHandle, T)>,
50}
51
52impl<M, T> Default for BasicSubject<M, T> {
53    fn default() -> Self {
54        Self::new()
55    }
56}
57
58impl<M, T> BasicSubject<M, T> {
59    pub const fn new() -> Self {
60        Self {
61            _data: PhantomData,
62            trackers: Vec::new(),
63        }
64    }
65
66    pub fn trackers(&self) -> Trackers<'_, T> {
67        Trackers::new(self.trackers.iter())
68    }
69
70    pub fn add_tracker(&mut self, tracker: T) -> TrackerHandle {
71        let handle = TrackerHandle::new();
72        self.trackers.push((handle, tracker));
73        handle
74    }
75
76    pub fn remove_tracker(&mut self, tracker: TrackerHandle) {
77        let found_index = self.trackers.iter().position(|&(it, _)| it == tracker);
78        if let Some(idx) = found_index {
79            _ = self.trackers.remove(idx);
80        }
81    }
82}
83
84pub struct Trackers<'a, T> {
85    inner: slice::Iter<'a, (TrackerHandle, T)>,
86}
87
88impl<'a, T> Trackers<'a, T> {
89    const fn new(trackers: slice::Iter<'a, (TrackerHandle, T)>) -> Self {
90        Self { inner: trackers }
91    }
92}
93
94impl<'a, T> Iterator for Trackers<'a, T> {
95    type Item = &'a T;
96
97    fn next(&mut self) -> Option<Self::Item> {
98        self.inner.next().map(|(_, tracker)| tracker)
99    }
100}