output_tracker/inner_subject/
mod.rs1use 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}