dfir_rs/scheduled/handoff/
tee.rs1use std::cell::RefCell;
4use std::collections::VecDeque;
5use std::rc::Rc;
6
7use super::{CanReceive, Handoff, HandoffMeta};
8
9struct ReaderHandoff<T> {
10 contents: VecDeque<Vec<T>>,
11}
12
13impl<T> Default for ReaderHandoff<T> {
14 fn default() -> Self {
15 Self {
16 contents: Default::default(),
17 }
18 }
19}
20
21struct TeeingHandoffInternal<T> {
22 readers: Vec<(bool, ReaderHandoff<T>)>,
24}
25
26#[derive(Clone)]
29pub struct TeeingHandoff<T>
30where
31 T: 'static,
32{
33 read_from: usize,
34 internal: Rc<RefCell<TeeingHandoffInternal<T>>>,
35}
36
37impl<T> Default for TeeingHandoff<T> {
38 fn default() -> Self {
39 TeeingHandoff {
40 read_from: 0,
41 internal: Rc::new(RefCell::new(TeeingHandoffInternal {
42 readers: vec![(true, ReaderHandoff::<T>::default())],
43 })),
44 }
45 }
46}
47
48impl<T> TeeingHandoff<T>
49where
50 T: Clone,
51{
52 #[must_use]
54 pub(crate) fn tee(&self) -> Self {
55 let id = (*self.internal).borrow().readers.len();
56 (*self.internal)
57 .borrow_mut()
58 .readers
59 .push((true, ReaderHandoff::default()));
60 Self {
61 read_from: id,
62 internal: self.internal.clone(),
63 }
64 }
65
66 pub(crate) fn drop(&self) {
68 self.internal.borrow_mut().readers[self.read_from].0 = false;
69 }
70}
71
72impl<T> HandoffMeta for TeeingHandoff<T> {
73 fn is_bottom(&self) -> bool {
75 self.internal.borrow().readers[self.read_from]
76 .1
77 .contents
78 .iter()
79 .all(Vec::is_empty)
80 }
81}
82
83impl<T> Handoff for TeeingHandoff<T> {
84 type Inner = VecDeque<Vec<T>>;
85
86 fn take_inner(&self) -> Self::Inner {
87 std::mem::take(
88 &mut (*self.internal).borrow_mut().readers[self.read_from]
89 .1
90 .contents,
91 )
92 }
93
94 fn borrow_mut_swap(&self) -> std::cell::RefMut<'_, Self::Inner> {
95 todo!()
96 }
97}
98
99impl<T> CanReceive<Vec<T>> for TeeingHandoff<T>
100where
101 T: Clone,
102{
103 fn give(&self, vec: Vec<T>) -> Vec<T> {
104 let readers = &mut (*self.internal).borrow_mut().readers;
105 if let Some((last, rest)) = readers.split_last_mut() {
106 for reader in rest {
107 if reader.0 {
108 reader.1.contents.push_back(vec.clone());
109 }
110 }
111 if last.0 {
112 last.1.contents.push_back(vec);
113 }
114 }
115 Vec::new()
116 }
117}